From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/SaWMan/src/Makefile.am | 62 + Source/SaWMan/src/Makefile.in | 538 ++++++ Source/SaWMan/src/isawman.c | 343 ++++ Source/SaWMan/src/isawman.h | 61 + Source/SaWMan/src/isawmanmanager.c | 718 +++++++ Source/SaWMan/src/isawmanmanager.h | 48 + Source/SaWMan/src/sawman.c | 3522 +++++++++++++++++++++++++++++++++++ Source/SaWMan/src/sawman_config.c | 512 +++++ Source/SaWMan/src/sawman_config.h | 76 + Source/SaWMan/src/sawman_draw.c | 677 +++++++ Source/SaWMan/src/sawman_draw.h | 55 + Source/SaWMan/src/sawman_internal.h | 573 ++++++ 12 files changed, 7185 insertions(+) create mode 100755 Source/SaWMan/src/Makefile.am create mode 100755 Source/SaWMan/src/Makefile.in create mode 100755 Source/SaWMan/src/isawman.c create mode 100755 Source/SaWMan/src/isawman.h create mode 100755 Source/SaWMan/src/isawmanmanager.c create mode 100755 Source/SaWMan/src/isawmanmanager.h create mode 100755 Source/SaWMan/src/sawman.c create mode 100755 Source/SaWMan/src/sawman_config.c create mode 100755 Source/SaWMan/src/sawman_config.h create mode 100755 Source/SaWMan/src/sawman_draw.c create mode 100755 Source/SaWMan/src/sawman_draw.h create mode 100755 Source/SaWMan/src/sawman_internal.h (limited to 'Source/SaWMan/src') diff --git a/Source/SaWMan/src/Makefile.am b/Source/SaWMan/src/Makefile.am new file mode 100755 index 0000000..7cdfd29 --- /dev/null +++ b/Source/SaWMan/src/Makefile.am @@ -0,0 +1,62 @@ +## Makefile.am for SaWMan/src + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ + $(DFB_CFLAGS) + +AM_CPPFLAGS = \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \ + -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\" \ + -DSYSCONFDIR=\"@sysconfdir@\" + + +lib_LTLIBRARIES = libsawman.la + +libsawman_la_SOURCES = \ + isawman.c \ + isawman.h \ + isawmanmanager.c \ + isawmanmanager.h \ + sawman.c \ + sawman_internal.h \ + sawman_draw.c \ + sawman_draw.h \ + sawman_config.c \ + sawman_config.h + +libsawman_la_LIBADD = \ + $(DFB_LIBS) + +libsawman_la_LDFLAGS = \ + -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ + -release $(LT_RELEASE) + + +# +## and now rebuild the static version with the *correct* object files +# +if BUILD_STATIC + +clean-local: + rm -f libsawman_fixed.a + +all-local: libsawman_fixed.a + +libsawman_fixed.a: .libs/libsawman.a + rm -f libsawman_fixed.a + ${AR} cru libsawman_fixed.a `find . -name "*.o" | grep -v '.libs'` + ${RANLIB} libsawman_fixed.a + cp -pf libsawman_fixed.a .libs/libsawman.a + +.libs/libsawman.a: libsawman.la + +else + +clean-local: + +all-local: + +endif diff --git a/Source/SaWMan/src/Makefile.in b/Source/SaWMan/src/Makefile.in new file mode 100755 index 0000000..d03bc58 --- /dev/null +++ b/Source/SaWMan/src/Makefile.in @@ -0,0 +1,538 @@ +# 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@ +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libsawman_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libsawman_la_OBJECTS = isawman.lo isawmanmanager.lo sawman.lo \ + sawman_draw.lo sawman_config.lo +libsawman_la_OBJECTS = $(am_libsawman_la_OBJECTS) +libsawman_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libsawman_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 = $(libsawman_la_SOURCES) +DIST_SOURCES = $(libsawman_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +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 = @DFB_CFLAGS@ +DFB_LIBS = @DFB_LIBS@ +DSYMUTIL = @DSYMUTIL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_AGE = @LT_AGE@ +LT_CURRENT = @LT_CURRENT@ +LT_RELEASE = @LT_RELEASE@ +LT_REVISION = @LT_REVISION@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MODULEDIR = @MODULEDIR@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +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@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SAWMAN_BINARY_AGE = @SAWMAN_BINARY_AGE@ +SAWMAN_INTERFACE_AGE = @SAWMAN_INTERFACE_AGE@ +SAWMAN_MAJOR_VERSION = @SAWMAN_MAJOR_VERSION@ +SAWMAN_MICRO_VERSION = @SAWMAN_MICRO_VERSION@ +SAWMAN_MINOR_VERSION = @SAWMAN_MINOR_VERSION@ +SAWMAN_VERSION = @SAWMAN_VERSION@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +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_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ + $(DFB_CFLAGS) + +AM_CPPFLAGS = \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \ + -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\" \ + -DSYSCONFDIR=\"@sysconfdir@\" + +lib_LTLIBRARIES = libsawman.la +libsawman_la_SOURCES = \ + isawman.c \ + isawman.h \ + isawmanmanager.c \ + isawmanmanager.h \ + sawman.c \ + sawman_internal.h \ + sawman_draw.c \ + sawman_draw.h \ + sawman_config.c \ + sawman_config.h + +libsawman_la_LIBADD = \ + $(DFB_LIBS) + +libsawman_la_LDFLAGS = \ + -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ + -release $(LT_RELEASE) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsawman.la: $(libsawman_la_OBJECTS) $(libsawman_la_DEPENDENCIES) + $(libsawman_la_LINK) -rpath $(libdir) $(libsawman_la_OBJECTS) $(libsawman_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isawman.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isawmanmanager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sawman.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sawman_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sawman_draw.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) all-local +installdirs: + for dir in "$(DESTDIR)$(libdir)"; 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-libLTLIBRARIES clean-libtool clean-local \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES + + +# +# + +@BUILD_STATIC_TRUE@clean-local: +@BUILD_STATIC_TRUE@ rm -f libsawman_fixed.a + +@BUILD_STATIC_TRUE@all-local: libsawman_fixed.a + +@BUILD_STATIC_TRUE@libsawman_fixed.a: .libs/libsawman.a +@BUILD_STATIC_TRUE@ rm -f libsawman_fixed.a +@BUILD_STATIC_TRUE@ ${AR} cru libsawman_fixed.a `find . -name "*.o" | grep -v '.libs'` +@BUILD_STATIC_TRUE@ ${RANLIB} libsawman_fixed.a +@BUILD_STATIC_TRUE@ cp -pf libsawman_fixed.a .libs/libsawman.a + +@BUILD_STATIC_TRUE@.libs/libsawman.a: libsawman.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/SaWMan/src/isawman.c b/Source/SaWMan/src/isawman.c new file mode 100755 index 0000000..f241023 --- /dev/null +++ b/Source/SaWMan/src/isawman.c @@ -0,0 +1,343 @@ +/* + (c) Copyright 2006-2007 directfb.org + + All rights reserved. + + Written by Denis Oliver Kropp . + + 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 + +#include +#include +#include + +#include +#include + +#include +#include + +#include "isawman.h" +#include "isawmanmanager.h" + + +static ReactionResult ISaWMan_Tier_Update( const void *msg_data, + void *ctx ); + +/**********************************************************************************************************************/ + +static void +ISaWMan_Destruct( ISaWMan *thiz ) +{ + ISaWMan_data *data = thiz->priv; + + fusion_reactor_detach( ((SaWManTier*) data->sawman->tiers)->reactor, &data->reaction ); + + pthread_mutex_destroy( &data->lock ); + pthread_cond_destroy( &data->cond ); + + dfb_updates_deinit( &data->updates ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +/**********************************************************************************************************************/ + +static DirectResult +ISaWMan_AddRef( ISaWMan *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( ISaWMan ) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +ISaWMan_Release( ISaWMan *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( ISaWMan ) + + if (--data->ref == 0) + ISaWMan_Destruct( thiz ); + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +static DirectResult +ISaWMan_Start( ISaWMan *thiz, + const char *name, + pid_t *ret_pid ) +{ + int ret; + char *tmp = NULL; + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWMan ) + + if (!name) + return DFB_INVARG; + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + + ret = sawman_lock( sawman ); + if (ret) + goto out; + + tmp = SHSTRDUP( sawman->shmpool, name ); + if (!tmp) { + ret = D_OOSHM(); + goto out; + } + + ret = sawman_call( sawman, SWMCID_START, tmp ); + if (ret < 0) { + if (ret_pid) + *ret_pid = -ret; + ret = DFB_OK; + } + +out: + if (tmp) + SHFREE( sawman->shmpool, tmp ); + + sawman_unlock( sawman ); + + return ret; +} + +static DirectResult +ISaWMan_Stop( ISaWMan *thiz, + pid_t pid ) +{ + DirectResult ret; + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWMan ) + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + + ret = sawman_lock( sawman ); + if (ret) + return ret; + + ret = sawman_call( sawman, SWMCID_STOP, (void*)(long) pid ); + + sawman_unlock( sawman ); + + return ret; +} + +static DirectResult +ISaWMan_ReturnKeyEvent( ISaWMan *thiz, + DFBWindowEvent *event ) +{ + DirectResult ret; + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!event) + return DFB_INVARG; + + /* Only key events! */ + if (event->type != DWET_KEYDOWN && event->type != DWET_KEYUP) + return DFB_UNSUPPORTED; + + /* Don't return same event twice! 'flags' is only valid for KEY events. */ + if (event->flags & DWEF_RETURNED) + return DFB_LIMITEXCEEDED; + + event->flags |= DWEF_RETURNED; + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + + ret = sawman_lock( sawman ); + if (ret) + return ret; + + if (sawman->unselkeys_window) + ret = sawman_post_event( sawman, sawman->unselkeys_window, event ); + + sawman_unlock( sawman ); + + return ret; +} + +static DirectResult +ISaWMan_CreateManager( ISaWMan *thiz, + const SaWManCallbacks *callbacks, + void *context, + ISaWManManager **ret_manager ) +{ + DirectResult ret; + ISaWManManager *manager; + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWMan ) + + if (!callbacks || !ret_manager) + return DFB_INVARG; + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + + ret = sawman_lock( sawman ); + if (ret) + return ret; + + ret = sawman_register( sawman, callbacks, context ); + if (ret) + goto out; + + DIRECT_ALLOCATE_INTERFACE( manager, ISaWManManager ); + + ret = ISaWManManager_Construct( manager, data->sawman, data->process ); + if (ret) { + /* FIXME: sawman_unregister! */ + goto out; + } + + *ret_manager = manager; + + /* + * Attach to existing entities. + */ + if (callbacks->ProcessAdded) { + SaWManProcess *process; + + direct_list_foreach (process, sawman->processes) { + D_MAGIC_ASSERT( process, SaWManProcess ); + + callbacks->ProcessAdded( context, process ); + } + } + + if (callbacks->WindowAdded) { + SaWManWindow *window; + SaWManWindowInfo *info; + + info = &sawman->callback.info; + direct_list_foreach (window, sawman->windows) { + D_MAGIC_ASSERT( window, SaWManWindow ); + info->handle = (SaWManWindowHandle)window; + info->caps = window->caps; + SAWMANWINDOWCONFIG_COPY( &info->config, &window->window->config ) + + callbacks->WindowAdded( context, info ); + } + } + + +out: + sawman_unlock( sawman ); + + return ret; +} + +static DirectResult +ISaWMan_GetUpdates( ISaWMan *thiz, + DFBWindowStackingClass stacking_class, + DFBRegion *ret_updates, + unsigned int *ret_num ) +{ + DIRECT_INTERFACE_GET_DATA( ISaWMan ) + + if (!ret_updates || !ret_num) + return DFB_INVARG; + + pthread_mutex_lock( &data->lock ); + + while (!data->updates.num_regions) { + pthread_cond_wait( &data->cond, &data->lock ); + } + + direct_memcpy( ret_updates, data->updates.regions, sizeof(DFBRegion) * data->updates.num_regions ); + + *ret_num = data->updates.num_regions; + + dfb_updates_reset( &data->updates ); + + pthread_mutex_unlock( &data->lock ); + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +DirectResult +ISaWMan_Construct( ISaWMan *thiz, + SaWMan *sawman, + SaWManProcess *process ) +{ + DIRECT_ALLOCATE_INTERFACE_DATA( thiz, ISaWMan ) + + data->ref = 1; + data->sawman = sawman; + data->process = process; + + pthread_mutex_init( &data->lock, NULL ); + pthread_cond_init( &data->cond, NULL ); + + dfb_updates_init( &data->updates, data->updates_regions, D_ARRAY_SIZE(data->updates_regions) ); + +// fusion_reactor_attach_channel( ((SaWManTier*) sawman->tiers->next)->reactor, +// SAWMAN_TIER_UPDATE, ISaWMan_Tier_Update, data, &data->reaction ); + + thiz->AddRef = ISaWMan_AddRef; + thiz->Release = ISaWMan_Release; + thiz->Start = ISaWMan_Start; + thiz->Stop = ISaWMan_Stop; + thiz->ReturnKeyEvent = ISaWMan_ReturnKeyEvent; + thiz->CreateManager = ISaWMan_CreateManager; + thiz->GetUpdates = ISaWMan_GetUpdates; + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +static ReactionResult +ISaWMan_Tier_Update( const void *msg_data, + void *ctx ) +{ + int i; + const SaWManTierUpdate *update = msg_data; + ISaWMan_data *data = ctx; + + pthread_mutex_lock( &data->lock ); + + for (i=0; inum_regions; i++) { + dfb_updates_add( &data->updates, &update->regions[i] ); + } + + pthread_mutex_unlock( &data->lock ); + + pthread_cond_broadcast( &data->cond ); + + return RS_OK; +} diff --git a/Source/SaWMan/src/isawman.h b/Source/SaWMan/src/isawman.h new file mode 100755 index 0000000..bf09038 --- /dev/null +++ b/Source/SaWMan/src/isawman.h @@ -0,0 +1,61 @@ +/* + (c) Copyright 2006-2007 directfb.org + + All rights reserved. + + Written by Denis Oliver Kropp . + + 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 __ISAWMAN_H__ +#define __ISAWMAN_H__ + + +#include +#include + +#include + +#include + + +/* + * private data struct of ISaWMan + */ +typedef struct { + int ref; /* reference counter */ + SaWMan *sawman; + SaWManProcess *process; + + pthread_mutex_t lock; + pthread_cond_t cond; + + DFBUpdates updates; + DFBRegion updates_regions[SAWMAN_MAX_UPDATE_REGIONS]; + + Reaction reaction; +} ISaWMan_data; + +/* + * ISaWMan constructor + */ +DirectResult ISaWMan_Construct( ISaWMan *thiz, + SaWMan *sawman, + SaWManProcess *process ); + +#endif + diff --git a/Source/SaWMan/src/isawmanmanager.c b/Source/SaWMan/src/isawmanmanager.c new file mode 100755 index 0000000..29779d1 --- /dev/null +++ b/Source/SaWMan/src/isawmanmanager.c @@ -0,0 +1,718 @@ +/* + (c) Copyright 2006-2007 directfb.org + + All rights reserved. + + Written by Denis Oliver Kropp . + + 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 + +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include "isawmanmanager.h" + + + +D_DEBUG_DOMAIN( SaWMan_Manager, "SaWMan/Manager", "SaWMan Manager Interface" ); + + +static void +ISaWManManager_Destruct( ISaWManManager *thiz ) +{ + ISaWManManager_data *data = thiz->priv; + + (void) data; + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + + +static DirectResult +ISaWManManager_AddRef( ISaWManManager *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +ISaWManManager_Release( ISaWManManager *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (--data->ref == 0) + ISaWManManager_Destruct( thiz ); + + return DFB_OK; +} + +static DirectResult +ISaWManManager_QueueUpdate( ISaWManManager *thiz, + DFBWindowStackingClass stacking, + const DFBRegion *region ) +{ + SaWMan *sawman; + SaWManTier *tier; + DFBRegion update; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!DFB_REGION_CHECK_IF( region )) + return DFB_INVAREA; + + switch (stacking) { + case DWSC_LOWER: + case DWSC_MIDDLE: + case DWSC_UPPER: + break; + + default: + return DFB_INVARG; + } + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + tier = sawman_tier_by_class( sawman, stacking ); + + update = DFB_REGION_INIT_FROM_DIMENSION( &tier->size ); + + if (region && !dfb_region_region_intersect( &update, region )) + return DFB_OK; + + dfb_updates_add( &tier->updates, &update ); + + return DFB_OK; +} + +static DirectResult +ISaWManManager_ProcessUpdates( ISaWManManager *thiz, + DFBSurfaceFlipFlags flags ) +{ + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + return sawman_process_updates( sawman, flags ); +} + +static DirectResult +ISaWManManager_CloseWindow( ISaWManManager *thiz, + SaWManWindowHandle handle ) +{ + SaWMan *sawman; + DFBWindowEvent event; + SaWManWindow *window = (SaWManWindow*)handle; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!window) + return DFB_INVARG; + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( window, SaWManWindow ); + + event.type = DWET_CLOSE; + + dfb_window_post_event( window->window, &event ); + + return DFB_OK; +} + +static DirectResult +ISaWManManager_SetVisible( ISaWManManager *thiz, + SaWManWindowHandle handle, + DFBBoolean visible ) +{ + SaWMan *sawman; + SaWManWindow *window = (SaWManWindow*)handle; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!window) + return DFB_INVARG; + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( window, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + D_UNIMPLEMENTED(); + + return DFB_UNIMPLEMENTED;// sawman_set_visible( sawman, window ); +} + +static DirectResult +ISaWManManager_SwitchFocus( ISaWManManager *thiz, + SaWManWindowHandle handle ) +{ + SaWMan *sawman; + SaWManWindow *window = (SaWManWindow*)handle; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!window) + return DFB_INVARG; + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( window, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + return sawman_switch_focus( sawman, window ); +} + +static DirectResult +ISaWManManager_GetSize( ISaWManManager *thiz, + DFBWindowStackingClass stacking, + DFBDimension *ret_size ) +{ + SaWMan *sawman; + SaWManTier *tier; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + switch (stacking) { + case DWSC_LOWER: + case DWSC_MIDDLE: + case DWSC_UPPER: + break; + + default: + return DFB_INVARG; + } + + if (!ret_size) + return DFB_INVARG; + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + tier = sawman_tier_by_class( sawman, stacking ); + + *ret_size = tier->size; + + return DFB_OK; +} + +static DirectResult +ISaWManManager_InsertWindow( ISaWManManager *thiz, + SaWManWindowHandle handle, + SaWManWindowHandle relative, + SaWManWindowRelation relation ) +{ + SaWMan *sawman; + SaWManWindow *window = (SaWManWindow*)handle; + SaWManWindow *sawrel = (SaWManWindow*)relative; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!window) + return DFB_INVARG; + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( window, SaWManWindow ); + D_MAGIC_ASSERT_IF( sawrel, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + return sawman_insert_window( sawman, window, sawrel, + (relation == SWMWR_TOP) ? DFB_TRUE : DFB_FALSE ); +} + +static DirectResult +ISaWManManager_RemoveWindow( ISaWManManager *thiz, + SaWManWindowHandle handle ) +{ + SaWMan *sawman; + SaWManWindow *window = (SaWManWindow*)handle; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!window) + return DFB_INVARG; + + sawman = data->sawman; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( window, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + return sawman_remove_window( sawman, window ); +} + +static DirectResult +ISaWManManager_SetScalingMode( ISaWManManager *thiz, + SaWManScalingMode mode ) +{ + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (mode != SWMSM_STANDARD && mode != SWMSM_SMOOTH_SW) + return DFB_INVARG; + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + if (sawman->scaling_mode != mode) { + SaWManTier *tier; + + sawman->scaling_mode = mode; + + direct_list_foreach (tier, sawman->tiers) { + DFBRegion update = DFB_REGION_INIT_FROM_DIMENSION( &tier->size ); + + dfb_updates_add( &tier->updates, &update ); + } + } + + return DFB_OK; +} + +static void +reset_geometry_to_nonfollow( SaWManWindow *window ) +{ + if (window->window->config.dst_geometry.mode == DWGM_FOLLOW) + window->window->config.dst_geometry.mode = DWGM_DEFAULT; + + if (window->window->config.src_geometry.mode == DWGM_FOLLOW) + window->window->config.src_geometry.mode = DWGM_DEFAULT; +} + + +static DirectResult +ISaWManManager_SetWindowConfig ( ISaWManManager *thiz, + SaWManWindowHandle handle, + SaWManWindowConfigFlags flags, + SaWManWindowConfig *config ) +{ + DFBResult ret; + SaWMan *sawman; + SaWManWindow *sawwin = (SaWManWindow*)handle; + CoreWindow *window; + + /* + not yet implemented: + SWMCF_KEY_SELECTION + */ + + if (flags & ~(SWMCF_ALL - SWMCF_KEY_SELECTION)) + return DFB_INVARG; + + if( config == NULL ) + return DFB_INVARG; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + window = sawwin->window; + D_ASSERT( window != NULL ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + if (flags & CWCF_OPTIONS) { + if ((window->config.options & DWOP_SCALE) && !(config->options & DWOP_SCALE) && window->surface) { + /* scaling turned off - see if we need to reallocate the 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/SaWMan: 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; + } + } + } + + if (config->options & (DWOP_KEEP_ABOVE | DWOP_KEEP_UNDER)) { + D_ASSERT( sawwin->parent ); + + if (config->options & DWOP_KEEP_ABOVE) { + D_ASSERT( sawman_window_priority(sawwin->parent) <= sawman_window_priority(sawwin) ); + + sawman_insert_window( sawman, sawwin, sawwin->parent, true ); + } + else { + D_ASSERT( sawman_window_priority(sawwin->parent) >= sawman_window_priority(sawwin) ); + + sawman_insert_window( sawman, sawwin, sawwin->parent, false ); + } + + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER | SWMUF_FORCE_COMPLETE ); + } + + window->config.options = config->options; + } + + if (flags & CWCF_EVENTS) + window->config.events = config->events; + + if (flags & CWCF_COLOR) + window->config.color = config->color; + + if (flags & CWCF_COLOR_KEY) + window->config.color_key = config->color_key; + + if (flags & CWCF_OPAQUE) + window->config.opaque = config->opaque; + + if (flags & CWCF_STACKING) + sawman_restack_window( sawman, sawwin, sawwin, 0, config->stacking ); + + if (flags & CWCF_OPACITY) + sawman_set_opacity( sawman, sawwin, config->opacity ); + + if( flags & (SWMCF_POSITION | SWMCF_SIZE) ) { + if( flags == SWMCF_POSITION ) { + window->config.bounds.x = config->bounds.x; + window->config.bounds.y = config->bounds.y; + } + else if( flags == SWMCF_SIZE ) { + window->config.bounds.w = config->bounds.w; + window->config.bounds.h = config->bounds.h; + } + else + window->config.bounds = config->bounds; + } + + if (flags & CWCF_SRC_GEOMETRY) + window->config.src_geometry = config->src_geometry; + + if (flags & CWCF_DST_GEOMETRY) + window->config.dst_geometry = config->dst_geometry; + + if (flags & SWMCF_ASSOCIATION && window->config.association != config->association) { + SaWManWindow *parent = sawwin->parent; + + /* Dissociate first */ + if (sawwin->parent_window) { + int index; + + dfb_window_unlink( &sawwin->parent_window ); + + index = fusion_vector_index_of( &parent->children, sawwin ); + D_ASSERT( index >= 0 ); + D_ASSERT( index < parent->children.count ); + + fusion_vector_remove( &parent->children, index ); + + sawwin->parent = NULL; + + window->config.association = 0; + } + + + + /* Lookup new parent window. */ + if (config->association) { + D_DEBUG_AT( SaWMan_Manager, " -> new parent win id %u\n", config->association ); + + direct_list_foreach (parent, sawman->windows) { + D_MAGIC_ASSERT( parent, SaWManWindow ); + D_ASSERT( parent->window != NULL ); + + if (parent->id == config->association) + break; + } + + if (!parent) { + D_ERROR( "SaWMan/WM: Can't find parent window with ID %d!\n", config->association ); + reset_geometry_to_nonfollow( sawwin ); + return DFB_IDNOTFOUND; + } + + D_MAGIC_ASSERT( parent, SaWManWindow ); + D_ASSERT( parent->window != NULL ); + + if (parent->window->toplevel != window->toplevel) { + D_ERROR( "SaWMan/WM: Can't associate windows with different toplevel!\n" ); + reset_geometry_to_nonfollow( sawwin ); + return DFB_INVARG; + } + + D_DEBUG_AT( SaWMan_Manager, " -> parent window %p\n", parent ); + + + ret = dfb_window_link( &sawwin->parent_window, parent->window ); + if (ret) { + D_DERROR( ret, "SaWMan/WM: Can't link parent window with ID %d!\n", config->association ); + reset_geometry_to_nonfollow( sawwin ); + return ret; + } + + ret = fusion_vector_add( &parent->children, sawwin ); + if (ret) { + dfb_window_unlink( &sawwin->parent_window ); + reset_geometry_to_nonfollow( sawwin ); + return ret; + } + + + sawwin->parent = parent; + + /* Write back new association */ + window->config.association = config->association; + } + else + reset_geometry_to_nonfollow( sawwin ); + } + + if (flags & (CWCF_POSITION | CWCF_SIZE | CWCF_SRC_GEOMETRY | CWCF_DST_GEOMETRY | SWMCF_ASSOCIATION)) + sawman_update_geometry( sawwin ); + + /* Send notification to windows watchers */ + CoreLayer *layer = dfb_layer_at( sawwin->stack->context->layer_id ); + dfb_wm_dispatch_WindowConfig( layer->core, window, flags ); + + return DFB_OK; +} + + + +static DirectResult +ISaWManManager_SendWindowEvent( ISaWManManager *thiz, + SaWManWindowHandle handle, + const DFBWindowEvent *event ) +{ + SaWMan *sawman; + SaWManWindow *window = (SaWManWindow*)handle; + DFBWindowEvent evt; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!event || (handle == SAWMAN_WINDOW_NONE)) + return DFB_INVARG; + + /* Only key events! */ + if (event->type != DWET_KEYDOWN && event->type != DWET_KEYUP) + return DFB_UNSUPPORTED; + + /* Don't return same event twice! */ + if (event->flags & DWEF_RETURNED) + return DFB_LIMITEXCEEDED; + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( window, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + evt = *event; + sawman_post_event( sawman, window, &evt ); + + return DFB_OK; +} + +static DirectResult +ISaWManManager_Lock( ISaWManManager *thiz ) +{ + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + + return sawman_lock( sawman ); +} + +static DirectResult +ISaWManManager_Unlock( ISaWManManager *thiz ) +{ + SaWMan *sawman; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + return sawman_unlock( sawman ); +} + +static DirectResult +ISaWManManager_GetWindowInfo( ISaWManManager *thiz, + SaWManWindowHandle handle, + SaWManWindowInfo *info ) +{ + SaWMan *sawman; + SaWManWindow *sawwin = (SaWManWindow*)handle; + CoreWindow *window; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!info || (handle == SAWMAN_WINDOW_NONE)) + return DFB_INVARG; + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + window = sawwin->window; + D_ASSERT( window != NULL ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + info->handle = handle; + info->caps = sawwin->caps; + SAWMANWINDOWCONFIG_COPY( &info->config, &window->config ) + info->config.key_selection = window->config.key_selection; + info->config.keys = window->config.keys; + info->config.num_keys = window->config.num_keys; + info->resource_id = window->resource_id; + info->win_id = window->id; + info->flags = sawwin->flags + | (window->flags & CWF_FOCUSED ? SWMWF_FOCUSED : 0) + | (window->flags & CWF_ENTERED ? SWMWF_ENTERED : 0); + + return DFB_OK; +} + +static DirectResult +ISaWManManager_GetProcessInfo( ISaWManManager *thiz, + SaWManWindowHandle handle, + SaWManProcess *process ) +{ + SaWMan *sawman; + SaWManWindow *sawwin = (SaWManWindow*)handle; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!process || (handle == SAWMAN_WINDOW_NONE)) + return DFB_INVARG; + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + *process = *sawwin->process; + + return DFB_OK; +} + +static DirectResult +ISaWManManager_IsWindowShowing( ISaWManManager *thiz, + SaWManWindowHandle handle, + DFBBoolean *ret_showing ) +{ + DFBResult ret; + bool showing; + SaWMan *sawman; + SaWManWindow *sawwin = (SaWManWindow*)handle; + + DIRECT_INTERFACE_GET_DATA( ISaWManManager ) + + if (!ret_showing) + return DFB_INVARG; + + sawman = data->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + ret = sawman_showing_window( sawman, sawwin, &showing ); + if (ret) + return ret; + + *ret_showing = showing ? DFB_TRUE : DFB_FALSE; + + return DFB_OK; +} + +DirectResult +ISaWManManager_Construct( ISaWManManager *thiz, + SaWMan *sawman, + SaWManProcess *process ) +{ + DIRECT_ALLOCATE_INTERFACE_DATA( thiz, ISaWManManager ) + + data->ref = 1; + data->sawman = sawman; + data->process = process; + + thiz->AddRef = ISaWManManager_AddRef; + thiz->Release = ISaWManManager_Release; + thiz->QueueUpdate = ISaWManManager_QueueUpdate; + thiz->ProcessUpdates = ISaWManManager_ProcessUpdates; + thiz->CloseWindow = ISaWManManager_CloseWindow; + thiz->SetVisible = ISaWManManager_SetVisible; + thiz->SwitchFocus = ISaWManManager_SwitchFocus; + thiz->GetSize = ISaWManManager_GetSize; + thiz->InsertWindow = ISaWManManager_InsertWindow; + thiz->RemoveWindow = ISaWManManager_RemoveWindow; + thiz->SetScalingMode = ISaWManManager_SetScalingMode; + thiz->SetWindowConfig = ISaWManManager_SetWindowConfig; + thiz->SendWindowEvent = ISaWManManager_SendWindowEvent; + thiz->Lock = ISaWManManager_Lock; + thiz->Unlock = ISaWManManager_Unlock; + thiz->GetWindowInfo = ISaWManManager_GetWindowInfo; + thiz->GetProcessInfo = ISaWManManager_GetProcessInfo; + thiz->IsWindowShowing = ISaWManManager_IsWindowShowing; + + return DFB_OK; +} diff --git a/Source/SaWMan/src/isawmanmanager.h b/Source/SaWMan/src/isawmanmanager.h new file mode 100755 index 0000000..67233ec --- /dev/null +++ b/Source/SaWMan/src/isawmanmanager.h @@ -0,0 +1,48 @@ +/* + (c) Copyright 2006-2007 directfb.org + + All rights reserved. + + Written by Denis Oliver Kropp . + + 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 __ISAWMANMANAGER_H__ +#define __ISAWMANMANAGER_H__ + + +#include + + +/* + * private data struct of ISaWManManager + */ +typedef struct { + int ref; /* reference counter */ + SaWMan *sawman; + SaWManProcess *process; +} ISaWManManager_data; + +/* + * ISaWManManager constructor + */ +DirectResult ISaWManManager_Construct( ISaWManManager *thiz, + SaWMan *sawman, + SaWManProcess *process ); + +#endif + diff --git a/Source/SaWMan/src/sawman.c b/Source/SaWMan/src/sawman.c new file mode 100755 index 0000000..d2510a7 --- /dev/null +++ b/Source/SaWMan/src/sawman.c @@ -0,0 +1,3522 @@ +/* + (c) Copyright 2006-2007 directfb.org + + All rights reserved. + + Written by Denis Oliver Kropp . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +//#define DIRECT_ENABLE_DEBUG + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include "sawman_config.h" +#include "sawman_draw.h" + +#include "isawman.h" + + +#ifndef DIRECTFB_PURE_VOODOO + +D_DEBUG_DOMAIN( SaWMan_Auto, "SaWMan/Auto", "SaWMan auto configuration" ); +D_DEBUG_DOMAIN( SaWMan_Update, "SaWMan/Update", "SaWMan window manager updates" ); +D_DEBUG_DOMAIN( SaWMan_Geometry, "SaWMan/Geometry", "SaWMan window manager geometry" ); +D_DEBUG_DOMAIN( SaWMan_Stacking, "SaWMan/Stacking", "SaWMan window manager stacking" ); +D_DEBUG_DOMAIN( SaWMan_FlipOnce, "SaWMan/FlipOnce", "SaWMan window manager flip once" ); +D_DEBUG_DOMAIN( SaWMan_Cursor, "SaWMan/Cursor", "SaWMan window manager cursor" ); +D_DEBUG_DOMAIN( SaWMan_Focus, "SaWMan/Focus", "SaWMan window manager focus" ); + + +/* FIXME: avoid globals */ +static SaWMan *m_sawman; +static SaWManProcess *m_process; +static FusionWorld *m_world; + +/**********************************************************************************************************************/ + +static void wind_of_change ( SaWMan *sawman, + SaWManTier *tier, + DFBRegion *update, + DFBSurfaceFlipFlags flags, + int current, + int changed ); + +static void wind_of_showing( SaWMan *sawman, + SaWManTier *tier, + DFBRegion *update, + int current, + int changed, + bool *ret_showing ); + +#endif // !DIRECTFB_PURE_VOODOO + +/**********************************************************************************************************************/ + +static DFBResult CreateRemote( const char *host, int session, ISaWMan **ret_sawman ); + +/**********************************************************************************************************************/ + +DirectResult +SaWManInit( int *argc, + char ***argv ) +{ +#ifndef DIRECTFB_PURE_VOODOO + return sawman_config_init( argc, argv ); +#else + return DR_OK; +#endif +} + +DirectResult +SaWManCreate( ISaWMan **ret_sawman ) +{ +#ifndef DIRECTFB_PURE_VOODOO + DirectResult ret; + ISaWMan *sawman; +#endif + + if (!ret_sawman) + return DFB_INVARG; + + direct_initialize(); + +#ifndef DIRECTFB_PURE_VOODOO + if (dfb_config->remote.host) + return CreateRemote( dfb_config->remote.host, dfb_config->remote.session, ret_sawman ); + + CoreDFB *core; + + dfb_core_create( &core ); + + if (!m_sawman) { + D_ERROR( "SaWManCreate: No running SaWMan detected! Did you use the 'wm=sawman' option?\n" ); + return DFB_NOIMPL; + } + + D_MAGIC_ASSERT( m_sawman, SaWMan ); + D_MAGIC_ASSERT( m_process, SaWManProcess ); + + DIRECT_ALLOCATE_INTERFACE( sawman, ISaWMan ); + + ret = ISaWMan_Construct( sawman, m_sawman, m_process ); + if (ret) + return ret; + + *ret_sawman = sawman; + + return DFB_OK; +#else + return CreateRemote( dfb_config->remote.host ?: "", dfb_config->remote.session, ret_sawman ); +#endif +} + +/**********************************************************************************************************************/ + +static DFBResult +CreateRemote( const char *host, int session, ISaWMan **ret_sawman ) +{ + DFBResult ret; + DirectInterfaceFuncs *funcs; + void *interface; + + D_ASSERT( host != NULL ); + D_ASSERT( ret_sawman != NULL ); + + ret = DirectGetInterface( &funcs, "ISaWMan", "Requestor", NULL, NULL ); + if (ret) + return ret; + + ret = funcs->Allocate( &interface ); + if (ret) + return ret; + + ret = funcs->Construct( interface, host, session ); + if (ret) + return ret; + + *ret_sawman = interface; + + return DFB_OK; +} + +/**********************************************************************************************************************/ +#ifndef DIRECTFB_PURE_VOODOO + +static DirectResult +register_process( SaWMan *sawman, + SaWManProcessFlags flags, + FusionWorld *world ) +{ + DirectResult ret; + SaWManProcess *process; + + D_MAGIC_ASSERT( sawman, SaWMan ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + /* Allocate process data. */ + process = SHCALLOC( sawman->shmpool, 1, sizeof(SaWManProcess) ); + if (!process) + return D_OOSHM(); + + /* Initialize process data. */ + process->pid = getpid(); + process->fusion_id = fusion_id( world ); + process->flags = flags; + + /* Initialize reference counter. */ + ret = fusion_ref_init( &process->ref, "SaWMan Process", world ); + if (ret) { + D_DERROR( ret, "SaWMan/Register: fusion_ref_init() failed!\n" ); + goto error_ref; + } + + /* Add a local reference. */ + ret = fusion_ref_up( &process->ref, false ); + if (ret) { + D_DERROR( ret, "SaWMan/Register: fusion_ref_up() failed!\n" ); + goto error; + } + + /* Set the process watcher on this. */ + ret = fusion_ref_watch( &process->ref, &sawman->process_watch, process->pid ); + if (ret) { + D_DERROR( ret, "SaWMan/Register: fusion_ref_watch() failed!\n" ); + goto error; + } + + D_MAGIC_SET( process, SaWManProcess ); + + /* Add process to list. */ + direct_list_append( &sawman->processes, &process->link ); + + /* Call application manager executable. */ + sawman_call( sawman, SWMCID_PROCESS_ADDED, process ); + + /* Set global singleton. */ + m_process = process; + + return DFB_OK; + + +error: + fusion_ref_destroy( &process->ref ); + +error_ref: + SHFREE( sawman->shmpool, process ); + + return ret; +} + +static DirectResult +unregister_process( SaWMan *sawman, + SaWManProcess *process ) +{ + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( process, SaWManProcess ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + /* Destroy reference counter. */ + fusion_ref_destroy( &process->ref ); + + /* Remove process from list. */ + direct_list_remove( &sawman->processes, &process->link ); + + /* Unregister manager process? */ + if (process->flags & SWMPF_MANAGER) { + D_ASSERT( sawman->manager.present ); + + /* Destroy manager call, unless it was another process. */ + if (m_process == process) + fusion_call_destroy( &sawman->manager.call ); + else + sawman->manager.call.handler = NULL; /* FIXME: avoid failing assertion in fusion_call_init() */ + + /* Ready for new manager. */ + sawman->manager.present = false; + } + else { + /* Call application manager executable. */ + sawman_call( sawman, SWMCID_PROCESS_REMOVED, process ); + } + + D_MAGIC_CLEAR( process ); + + /* Deallocate process data. */ + SHFREE( sawman->shmpool, process ); + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +static FusionCallHandlerResult +process_watcher( int caller, + int call_arg, + void *call_ptr, + void *ctx, + unsigned int serial, + int *ret_val ) +{ + DFBResult ret; + SaWMan *sawman = ctx; + SaWManProcess *process; + + D_MAGIC_ASSERT( sawman, SaWMan ); + + /* Lookup process by pid. */ + direct_list_foreach (process, sawman->processes) { + D_MAGIC_ASSERT( process, SaWManProcess ); + + if (process->pid == call_arg) + break; + } + + if (!process) { + D_BUG( "process with pid %d not found", call_arg ); + *ret_val = DFB_BUG; + return FCHR_RETURN; + } + + D_INFO( "SaWMan/Watcher: Process %d [%lu] has exited%s\n", process->pid, + process->fusion_id, (process->flags & SWMPF_EXITING) ? "." : " ABNORMALLY!" ); + + ret = sawman_lock( sawman ); + if (ret) + D_DERROR( ret, "SaWMan/%s(): sawman_lock() failed!\n", __FUNCTION__ ); + else { + unregister_process( sawman, process ); + + sawman_unlock( sawman ); + } + + return FCHR_RETURN; +} + +static FusionCallHandlerResult +manager_call_handler( int caller, + int call_arg, + void *call_ptr, + void *ctx, + unsigned int serial, + int *ret_val ) +{ + DirectResult ret; + SaWMan *sawman = ctx; + SaWManCallID call = call_arg; + + D_MAGIC_ASSERT( sawman, SaWMan ); + + /* Last mile of dispatch. */ + switch (call) { + case SWMCID_START: + if (sawman->manager.callbacks.Start) { + pid_t pid; + + ret = sawman->manager.callbacks.Start( sawman->manager.context, call_ptr, &pid ); + if (ret) + *ret_val = ret; + else + *ret_val = -pid; + } + break; + + case SWMCID_STOP: + if (sawman->manager.callbacks.Stop) + *ret_val = sawman->manager.callbacks.Stop( sawman->manager.context, (long) call_ptr, caller ); + break; + + case SWMCID_PROCESS_ADDED: + if (sawman->manager.callbacks.ProcessAdded) + *ret_val = sawman->manager.callbacks.ProcessAdded( sawman->manager.context, call_ptr ); + break; + + case SWMCID_PROCESS_REMOVED: + if (sawman->manager.callbacks.ProcessRemoved) + *ret_val = sawman->manager.callbacks.ProcessRemoved( sawman->manager.context, call_ptr ); + break; + + case SWMCID_INPUT_FILTER: + if (sawman->manager.callbacks.InputFilter) + *ret_val = sawman->manager.callbacks.InputFilter( sawman->manager.context, call_ptr ); + break; + + case SWMCID_WINDOW_PRECONFIG: + if (sawman->manager.callbacks.WindowPreConfig) + *ret_val = sawman->manager.callbacks.WindowPreConfig( sawman->manager.context, call_ptr ); + break; + + case SWMCID_WINDOW_ADDED: + if (sawman->manager.callbacks.WindowAdded) + *ret_val = sawman->manager.callbacks.WindowAdded( sawman->manager.context, call_ptr ); + break; + + case SWMCID_WINDOW_REMOVED: + if (sawman->manager.callbacks.WindowRemoved) + *ret_val = sawman->manager.callbacks.WindowRemoved( sawman->manager.context, call_ptr ); + break; + + case SWMCID_WINDOW_RECONFIG: + if (sawman->manager.callbacks.WindowReconfig) + *ret_val = sawman->manager.callbacks.WindowReconfig( sawman->manager.context, call_ptr ); + break; + + case SWMCID_WINDOW_RESTACK: + if (sawman->manager.callbacks.WindowRestack) + *ret_val = sawman->manager.callbacks.WindowRestack( sawman->manager.context, + sawman->callback.handle, + sawman->callback.relative, + (SaWManWindowRelation)call_ptr ); + break; + + case SWMCID_STACK_RESIZED: + if (sawman->manager.callbacks.StackResized) + *ret_val = sawman->manager.callbacks.StackResized( sawman->manager.context, call_ptr ); + break; + + case SWMCID_SWITCH_FOCUS: + if (sawman->manager.callbacks.SwitchFocus) + *ret_val = sawman->manager.callbacks.SwitchFocus( sawman->manager.context, + (SaWManWindowHandle)call_ptr ); + break; + + case SWMCID_LAYER_RECONFIG: + if (sawman->manager.callbacks.LayerReconfig) + *ret_val = sawman->manager.callbacks.LayerReconfig( sawman->manager.context, call_ptr ); + break; + + default: + *ret_val = DFB_NOIMPL; + } + + return FCHR_RETURN; +} + +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ + +static DFBResult +init_hw_cursor( SaWMan *sawman ) +{ + DFBResult ret; + + sawman->cursor.layer = dfb_layer_at( sawman_config->cursor.layer_id ); + D_ASSERT( sawman->cursor.layer != NULL ); + + ret = dfb_layer_create_context( sawman->cursor.layer, &sawman->cursor.context ); + if (ret) { + D_DERROR( ret, "SaWMan/Cursor: Could not create context at layer (id %u)!\n", sawman_config->cursor.layer_id ); + return ret; + } + + ret = dfb_layer_region_create( sawman->cursor.context, &sawman->cursor.region ); + if (ret) { + D_DERROR( ret, "SaWMan/Cursor: Could not create region at layer (id %u)!\n", sawman_config->cursor.layer_id ); + dfb_layer_context_unref( sawman->cursor.context ); + return ret; + } + + dfb_layer_activate_context( sawman->cursor.layer, sawman->cursor.context ); + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +static DirectResult +add_tier( SaWMan *sawman, + FusionWorld *world, + DFBDisplayLayerID layer_id, + SaWManStackingClasses classes ) +{ + SaWManTier *tier; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( layer_id >= 0 ); + D_ASSERT( layer_id < MAX_LAYERS ); + D_ASSERT( (classes & 7) != 0 ); + D_ASSERT( (classes & ~7) == 0 ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + direct_list_foreach (tier, sawman->tiers) { + D_MAGIC_ASSERT( tier, SaWManTier ); + + if (tier->classes & classes) { + D_ERROR( "SaWMan/Tiers: Cannot add tier for layer %d's classes 0x%x which collides with " + "layer %d's classes 0x%x!\n", layer_id, classes, tier->layer_id, tier->classes ); + return DFB_BUSY; + } + + if (tier->layer_id == layer_id) { + D_ERROR( "SaWMan/Tiers: Cannot add tier with layer %d which is already added!\n", layer_id ); + return DFB_BUSY; + } + } + + tier = SHCALLOC( sawman->shmpool, 1, sizeof(SaWManTier) ); + if (!tier) + return D_OOSHM(); + + tier->layer_id = layer_id; + tier->classes = classes; + + tier->reactor = fusion_reactor_new( 0, "SaWMan Tier", world ); + + dfb_updates_init( &tier->updates, tier->update_regions, SAWMAN_MAX_UPDATE_REGIONS ); + + D_MAGIC_SET( tier, SaWManTier ); + + direct_list_append( &sawman->tiers, &tier->link ); + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +DirectResult +sawman_initialize( SaWMan *sawman, + FusionWorld *world, + SaWManProcess **ret_process ) +{ + int i; + DirectResult ret; + GraphicsDeviceInfo info; + + D_ASSERT( sawman != NULL ); + D_ASSERT( world != NULL ); + + D_ASSERT( m_sawman == NULL ); + + /* Initialize process watcher call. */ + ret = fusion_call_init( &sawman->process_watch, process_watcher, sawman, world ); + if (ret) + return ret; + + /* Create shared memory pool. */ + ret = fusion_shm_pool_create( world, "SaWMan Pool", 0x100000, fusion_config->debugshm, &sawman->shmpool ); + if (ret) + goto error; + + /* Initialize lock. */ + fusion_skirmish_init( &sawman->lock, "SaWMan", world ); + + /* Initialize window layout vector. */ + fusion_vector_init( &sawman->layout, 8, sawman->shmpool ); + + /* Default to HW Scaling if supported. */ + if (dfb_gfxcard_get_device_info( &info ), info.caps.accel & DFXL_STRETCHBLIT) + sawman->scaling_mode = SWMSM_STANDARD; + + /* Initialize grabbed keys. */ + for (i=0; ikeys[i].code = -1; + + D_MAGIC_SET( sawman, SaWMan ); + + sawman_lock( sawman ); + + sawman->resolution = sawman_config->resolution; + + /* Initialize tiers. */ + for (i=0; ilayers); i++) { + if (!dfb_config->layers[i].stacking) + continue; + + ret = add_tier( sawman, world, i, dfb_config->layers[i].stacking ); + if (ret) { + sawman_unlock( sawman ); + D_MAGIC_CLEAR( sawman ); + goto error; + } + } + + /* Set global singleton. */ + m_sawman = sawman; + m_world = world; + + /* Register ourself as a new process. */ + ret = register_process( sawman, SWMPF_MASTER, world ); + if (ret) { + sawman_unlock( sawman ); + D_MAGIC_CLEAR( sawman ); + goto error; + } + + sawman_unlock( sawman ); + + if (ret_process) + *ret_process = m_process; + + return DFB_OK; + + +error: + if (sawman->tiers) { + SaWManTier *tier; + DirectLink *next; + + direct_list_foreach_safe (tier, next, sawman->tiers) { + D_MAGIC_CLEAR( tier ); + SHFREE( sawman->shmpool, tier ); + } + } + + fusion_call_destroy( &sawman->process_watch ); + + m_sawman = NULL; + m_world = NULL; + m_process = NULL; + + return ret; +} + +DirectResult +sawman_post_init( SaWMan *sawman, + FusionWorld *world ) +{ + DFBResult ret; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( world != NULL ); + + D_ASSERT( m_sawman == sawman ); + D_ASSERT( m_world == world ); + D_MAGIC_ASSERT( m_process, SaWManProcess ); + + sawman_lock( sawman ); + + /* Initialize HW Cursor? */ + if (sawman_config->cursor.hw) { + ret = init_hw_cursor( sawman ); + if (ret) { + sawman_unlock( sawman ); + return ret; + } + } + + sawman_unlock( sawman ); + + return DFB_OK; +} + +DirectResult +sawman_join( SaWMan *sawman, + FusionWorld *world, + SaWManProcess **ret_process ) +{ + DirectResult ret; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( world != NULL ); + + D_ASSERT( m_sawman == NULL ); + + /* Set global singleton. */ + m_sawman = sawman; + m_world = world; + + /* Lock SaWMan. */ + ret = sawman_lock( sawman ); + if (ret) + goto error; + + /* Register ourself as a new process. */ + ret = register_process( sawman, SWMPF_NONE, world ); + + /* Unlock SaWMan. */ + sawman_unlock( sawman ); + + if (ret) + goto error; + + if (ret_process) + *ret_process = m_process; + + return DFB_OK; + + +error: + m_sawman = NULL; + m_world = NULL; + m_process = NULL; + + return ret; +} + +DirectResult +sawman_shutdown( SaWMan *sawman, + FusionWorld *world ) +{ + DirectResult ret; + DirectLink *next; + SaWManProcess *process; + SaWManWindow *sawwin; + SaWManGrabbedKey *key; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( world != NULL ); + + D_ASSERT( m_sawman == sawman ); + D_ASSERT( m_world == world ); + + D_ASSERT( sawman->processes != NULL ); + D_ASSERT( sawman->processes->next == NULL ); + + process = (SaWManProcess*) sawman->processes; + + D_ASSERT( process == m_process ); + D_ASSERT( process->fusion_id == fusion_id( world ) ); + + /* Lock SaWMan. */ + ret = sawman_lock( sawman ); + if (ret) + return ret; + + /* Shutdown our own process. */ + unregister_process( sawman, process ); + + /* Clear global singleton. */ + m_process = NULL; + + /* Destroy process watcher call. */ + fusion_call_destroy( &sawman->process_watch ); + + D_ASSERT( sawman->processes == NULL ); + D_ASSERT( !sawman->manager.present ); + + D_ASSUME( sawman->windows == NULL ); + + direct_list_foreach (sawwin, sawman->windows) { + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_ASSERT( sawwin->window != NULL ); + + D_WARN( "window %d,%d-%dx%d still there", DFB_RECTANGLE_VALS( &sawwin->bounds ) ); + + sawwin->window->stack = NULL; + } + + /* FIXME */ + D_ASSUME( !sawman->windows ); + D_ASSUME( !sawman->layout.count ); + + /* Destroy window layout vector. */ + fusion_vector_destroy( &sawman->layout ); + + /* Destroy lock. */ + fusion_skirmish_destroy( &sawman->lock ); + + /* Free grabbed keys. */ + direct_list_foreach_safe (key, next, sawman->grabbed_keys) { + SHFREE( key->owner->shmpool, key ); + } + + D_MAGIC_CLEAR( sawman ); + + /* Destroy shared memory pool. */ + fusion_shm_pool_destroy( world, sawman->shmpool ); + + /* Clear global singleton. */ + m_sawman = NULL; + m_world = NULL; + + return DFB_OK; +} + +DirectResult +sawman_leave( SaWMan *sawman, + FusionWorld *world ) +{ + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( world != NULL ); + + D_ASSERT( m_sawman == sawman ); + D_ASSERT( m_world == world ); + D_MAGIC_ASSERT( m_process, SaWManProcess ); + + /* Set 'cleanly exiting' flag. */ + m_process->flags |= SWMPF_EXITING; + + /* Clear global singletons. */ + m_sawman = NULL; + m_world = NULL; + m_process = NULL; + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +DirectResult +sawman_call( SaWMan *sawman, + SaWManCallID call, + void *ptr ) +{ + int ret = DFB_FUSION; + + D_MAGIC_ASSERT( sawman, SaWMan ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + D_ASSERT( m_sawman == sawman ); + + /* Check for presence of manager. */ + if (!sawman->manager.present) + return DFB_NOIMPL; + + /* Avoid useless context switches etc. */ + switch (call) { + case SWMCID_START: + if (!sawman->manager.callbacks.Start) + return DFB_NOIMPL; + break; + + case SWMCID_STOP: + if (!sawman->manager.callbacks.Stop) + return DFB_NOIMPL; + break; + + case SWMCID_PROCESS_ADDED: + if (!sawman->manager.callbacks.ProcessAdded) + return DFB_NOIMPL; + break; + + case SWMCID_PROCESS_REMOVED: + if (!sawman->manager.callbacks.ProcessRemoved) + return DFB_NOIMPL; + break; + + case SWMCID_INPUT_FILTER: + if (!sawman->manager.callbacks.InputFilter) + return DFB_NOIMPL; + break; + + case SWMCID_WINDOW_PRECONFIG: + if (!sawman->manager.callbacks.WindowPreConfig) + return DFB_NOIMPL; + break; + + case SWMCID_WINDOW_ADDED: + if (!sawman->manager.callbacks.WindowAdded) + return DFB_NOIMPL; + break; + + case SWMCID_WINDOW_REMOVED: + if (!sawman->manager.callbacks.WindowRemoved) + return DFB_NOIMPL; + break; + + case SWMCID_WINDOW_RECONFIG: + if (!sawman->manager.callbacks.WindowReconfig) + return DFB_NOIMPL; + break; + + case SWMCID_WINDOW_RESTACK: + if (!sawman->manager.callbacks.WindowRestack) + return DFB_NOIMPL; + break; + + case SWMCID_STACK_RESIZED: + if (!sawman->manager.callbacks.StackResized) + return DFB_NOIMPL; + break; + + case SWMCID_SWITCH_FOCUS: + if (!sawman->manager.callbacks.SwitchFocus) + return DFB_NOIMPL; + break; + + case SWMCID_LAYER_RECONFIG: + if (!sawman->manager.callbacks.LayerReconfig) + return DFB_NOIMPL; + break; + } + + /* Execute the call in the manager executable. */ + if (fusion_call_execute( &sawman->manager.call, FCEF_NONE, call, ptr, &ret )) + return DFB_NOIMPL; + + return ret; +} + +/**********************************************************************************************************************/ + +DirectResult +sawman_register( SaWMan *sawman, + const SaWManCallbacks *callbacks, + void *context ) +{ + DirectResult ret; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( callbacks != NULL ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + D_ASSERT( m_sawman == sawman ); + D_ASSERT( m_world != NULL ); + D_MAGIC_ASSERT( m_process, SaWManProcess ); + + /* Check if another manager already exists. */ + if (sawman->manager.present) + return DFB_BUSY; + + /* Initialize the call to the manager executable (ourself). */ + ret = fusion_call_init( &sawman->manager.call, manager_call_handler, sawman, m_world ); + if (ret) + return ret; + + /* Initialize manager data. */ + sawman->manager.callbacks = *callbacks; + sawman->manager.context = context; + + /* Set manager flag for our process. */ + m_process->flags |= SWMPF_MANAGER; + + /* Activate it at last. */ + sawman->manager.present = true; + + return DFB_OK; +} + +DirectResult +sawman_switch_focus( SaWMan *sawman, + SaWManWindow *to ) +{ + DirectResult ret; + DFBWindowEvent evt; + SaWManWindow *from; + + D_DEBUG_AT( SaWMan_Focus, "%s( %p, to %p )\n", __FUNCTION__, sawman, to ); + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT_IF( to, SaWManWindow ); + + from = sawman->focused_window; + D_MAGIC_ASSERT_IF( from, SaWManWindow ); + + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + if (from == to) + return DFB_OK; + +// PR brg36mgr#118432: [550r1ext][Unknown]Directfb changing focuswindow spontaneously. +// if (to && to->caps & DWCAPS_NOFOCUS) + if (to && to->window->caps & DWCAPS_NOFOCUS) { + D_DEBUG_AT( SaWMan_Focus, " -> DWCAPS_NOFOCUS, discarding focus switch!\n" ); + + return DFB_OK; // PR brg36mgr#118432: [550r1ext][Unknown]Directfb changing focuswindow spontaneously. + } + + if (to) { + switch (ret = sawman_call( sawman, SWMCID_SWITCH_FOCUS, to )) { + case DFB_OK: + case DFB_NOIMPL: + break; + + default: + D_DEBUG_AT( SaWMan_Focus, " -> application manager returned '%s'\n", DirectFBErrorString( ret ) ); + return ret; + } + } + + if (from) { + D_DEBUG_AT( SaWMan_Focus, " -> removing focus from %p\n", from ); + + evt.type = DWET_LOSTFOCUS; + + sawman_post_event( sawman, from, &evt ); + + if (sawman_window_border( from )) + sawman_update_window( sawman, from, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + } + + if (to) { + CoreWindow *window; + CoreLayer *layer; + + window = to->window; + D_MAGIC_ASSERT( window, CoreWindow ); + + layer = dfb_layer_at( window->stack->context->layer_id ); + +#ifndef OLD_COREWINDOWS_STRUCTURE + if (window->toplevel) { + CoreWindow *toplevel = window->toplevel; + + D_MAGIC_ASSERT( toplevel, CoreWindow ); + + toplevel->subfocus = window; + } + else if (window->subfocus) { + window = window->subfocus; + D_MAGIC_ASSERT( window, CoreWindow ); + + to = window->window_data; + D_MAGIC_ASSERT( to, SaWManWindow ); + } +#endif + + evt.type = DWET_GOTFOCUS; + + sawman_post_event( sawman, to, &evt ); + + if (sawman_window_border( to )) + sawman_update_window( sawman, to, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + + /* Send notification to windows watchers */ + dfb_wm_dispatch_WindowFocus( layer->core, to->window ); + } + + sawman->focused_window = to; + sawman->focused_window_switched = true; + sawman->focused_window_to = to; + + return DFB_OK; +} + +DirectResult +sawman_post_event( SaWMan *sawman, + SaWManWindow *sawwin, + DFBWindowEvent *event ) +{ + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_ASSERT( sawwin->window != NULL ); + D_ASSERT( event != NULL ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + event->buttons = sawman->buttons; + event->modifiers = sawman->modifiers; + event->locks = sawman->locks; + + dfb_window_post_event( sawwin->window, event ); + + return DFB_OK; +} + +DirectResult +sawman_update_window( SaWMan *sawman, + SaWManWindow *sawwin, + const DFBRegion *region, + DFBSurfaceFlipFlags flags, + SaWManUpdateFlags update_flags ) +{ + DFBRegion area; + CoreWindowStack *stack; + CoreWindow *window; + SaWManTier *tier; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + DFB_REGION_ASSERT_IF( region ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + stack = sawwin->stack; + window = sawwin->window; + + D_ASSERT( stack != NULL ); + D_MAGIC_COREWINDOW_ASSERT( window ); + + D_DEBUG_AT( SaWMan_Update, "%s( %p, %p )\n", __FUNCTION__, sawwin, region ); + + if (!SAWMAN_VISIBLE_WINDOW(window) && !(update_flags & SWMUF_FORCE_INVISIBLE)) + return DFB_OK; + + D_ASSUME( sawwin->flags & SWMWF_INSERTED ); + + /* Make sure window is inserted. */ + if (!(sawwin->flags & SWMWF_INSERTED)) { + D_DEBUG_AT( SaWMan_Update, " -> window %d not inserted!\n", window->id ); + return DFB_OK; + } + + tier = sawman_tier_by_class( sawman, window->config.stacking ); + + if (region) { + if ((update_flags & SWMUF_SCALE_REGION) && (window->config.options & DWOP_SCALE)) { + int sw = sawwin->src.w; + int sh = sawwin->src.h; + int dw = sawwin->dst.w; + int dh = sawwin->dst.h; + + /* horizontal */ + if (dw > sw) { + /* upscaling */ + area.x1 = (region->x1 - 1) * dw / sw; + area.x2 = (region->x2 + 1) * dw / sw; + } + else { + /* downscaling */ + area.x1 = region->x1 * dw / sw - 1; + area.x2 = region->x2 * dw / sw + 1; + } + + /* vertical */ + if (dh > sh) { + /* upscaling */ + area.y1 = (region->y1 - 1) * dh / sh; + area.y2 = (region->y2 + 1) * dh / sh; + } + else { + /* downscaling */ + area.y1 = region->y1 * dh / sh - 1; + area.y2 = region->y2 * dh / sh + 1; + } + + /* limit to window area */ + dfb_region_clip( &area, 0, 0, dw - 1, dh - 1 ); + + /* screen offset */ + dfb_region_translate( &area, sawwin->dst.x, sawwin->dst.y ); + } + else + area = DFB_REGION_INIT_TRANSLATED( region, sawwin->dst.x, sawwin->dst.y ); + } + else { + if ((update_flags & SWMUF_UPDATE_BORDER) && sawman_window_border( sawwin )) + area = DFB_REGION_INIT_FROM_RECTANGLE( &sawwin->bounds ); + else + area = DFB_REGION_INIT_FROM_RECTANGLE( &sawwin->dst ); + } + + if (!dfb_unsafe_region_intersect( &area, 0, 0, tier->size.w - 1, tier->size.h - 1 )) + return DFB_OK; + + if (update_flags & SWMUF_FORCE_COMPLETE) + dfb_updates_add( &tier->updates, &area ); + else + wind_of_change( sawman, tier, &area, flags, + fusion_vector_size( &sawman->layout ) - 1, + sawman_window_index( sawman, sawwin ) ); + + return DFB_OK; +} + +DirectResult +sawman_showing_window( SaWMan *sawman, + SaWManWindow *sawwin, + bool *ret_showing ) +{ + DFBRegion area; + CoreWindowStack *stack; + CoreWindow *window; + SaWManTier *tier; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + stack = sawwin->stack; + window = sawwin->window; + + D_ASSERT( stack != NULL ); + D_MAGIC_COREWINDOW_ASSERT( window ); + + if (!sawman_tier_by_stack( sawman, stack, &tier )) + return DFB_BUG; + + *ret_showing = false; + + if (!SAWMAN_VISIBLE_WINDOW(window)) + return DFB_OK; + + /* Make sure window is inserted. */ + if (!(sawwin->flags & SWMWF_INSERTED)) + return DFB_OK; + + area = DFB_REGION_INIT_FROM_RECTANGLE( &sawwin->bounds ); + + if (!dfb_unsafe_region_intersect( &area, 0, 0, stack->width - 1, stack->height - 1 )) + return DFB_OK; + + if (fusion_vector_has_elements( &sawman->layout ) && window >= 0) { + int num = fusion_vector_size( &sawman->layout ); + + wind_of_showing( sawman, tier, &area, num - 1, + sawman_window_index( sawman, sawwin ), ret_showing ); + } + else + *ret_showing = true; + + return DFB_OK; +} + +DirectResult +sawman_insert_window( SaWMan *sawman, + SaWManWindow *sawwin, + SaWManWindow *relative, + bool top ) +{ + DirectResult ret; + int index = 0; + SaWManWindow *other; + CoreWindow *window; + CoreLayer *layer; + + D_DEBUG_AT( SaWMan_Stacking, "%s( %p, %p, %p, %s )\n", __FUNCTION__, + sawman, sawwin, relative, top ? "top" : "below" ); + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_MAGIC_ASSERT_IF( relative, SaWManWindow ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + layer = dfb_layer_at( window->stack->context->layer_id ); + +#ifndef OLD_COREWINDOWS_STRUCTURE + /* In case of a sub window, the order from sub window vector is followed */ + if (window->toplevel) { + CoreWindow *toplevel = window->toplevel; + CoreWindow *tmp; + SaWManWindow *parent; + + /* Enforce association rules... */ + parent = sawwin->parent; + if (parent) { + D_MAGIC_ASSERT( parent, SaWManWindow ); + + tmp = parent->window; + D_ASSERT( tmp != NULL ); + D_ASSERT( tmp->toplevel == toplevel ); + + if (window->config.options & DWOP_KEEP_UNDER) { + int under; + + index = fusion_vector_index_of( &toplevel->subwindows, window ); + under = fusion_vector_index_of( &toplevel->subwindows, parent ); + + if (index < under - 1) { + D_DEBUG_AT( SaWMan_Stacking, " -> moving under (%d->%d)\n", index, under - 1 ); + + fusion_vector_move( &toplevel->subwindows, index, under - 1 ); + } + else if (index > under - 1) { + D_DEBUG_AT( SaWMan_Stacking, " -> moving under (%d<-%d)\n", under, index ); + + fusion_vector_move( &toplevel->subwindows, index, under ); + } + } + else if (window->config.options & DWOP_KEEP_ABOVE) { + int above; + + index = fusion_vector_index_of( &toplevel->subwindows, window ); + above = fusion_vector_index_of( &toplevel->subwindows, parent ); + + if (index < above + 1) { + D_DEBUG_AT( SaWMan_Stacking, " -> moving above (%d->%d)\n", index, above ); + + fusion_vector_move( &toplevel->subwindows, index, above ); + } + else if (index > above + 1) { + D_DEBUG_AT( SaWMan_Stacking, " -> moving above (%d<-%d)\n", above + 1, index ); + + fusion_vector_move( &toplevel->subwindows, index, above + 1 ); + } + } + } + + /* Lookup our index in top level window */ + index = fusion_vector_index_of( &toplevel->subwindows, window ); + + D_DEBUG_AT( SaWMan_Stacking, " -> toplevel %p [%4d,%4d-%4dx%4d] (%d)\n", + toplevel, DFB_RECTANGLE_VALS(&toplevel->config.bounds), index ); + + /* Get sub window below (or top level) */ + if (index == 0) + tmp = toplevel; + else + tmp = fusion_vector_at( &toplevel->subwindows, index - 1 ); + + D_DEBUG_AT( SaWMan_Stacking, " -> relative %p [%4d,%4d-%4dx%4d] (%d)\n", + tmp, DFB_RECTANGLE_VALS(&tmp->config.bounds), index - 1 ); + + /* Place on top */ + relative = tmp->window_data; + top = true; + } + else +#endif + if (sawwin->parent && (window->config.options & (DWOP_KEEP_ABOVE|DWOP_KEEP_UNDER))) { + D_MAGIC_ASSERT( sawwin->parent, SaWManWindow ); + + relative = sawwin->parent; + top = (window->config.options & DWOP_KEEP_ABOVE) ? true : false; + + D_MAGIC_ASSERT( relative, SaWManWindow ); + +#ifndef OLD_COREWINDOWS_STRUCTURE + if (top && relative->window->subwindows.count) { + CoreWindow *tmp; + + tmp = fusion_vector_at( &relative->window->subwindows, relative->window->subwindows.count - 1 ); + relative = tmp->window_data; + + D_MAGIC_ASSERT( relative, SaWManWindow ); + } +#endif + } + + + if (relative) + D_ASSUME( relative->priority == sawwin->priority ); + + if (relative) { + index = sawman_window_index( sawman, relative ); + D_ASSERT( index >= 0 ); + D_ASSERT( index < sawman->layout.count ); + + if (top) + index++; + } + else if (top) { + /* + * Iterate from bottom to top, + * stopping at the first window with a higher priority. + */ + fusion_vector_foreach (other, index, sawman->layout) { + D_MAGIC_ASSERT( other, SaWManWindow ); + + if (other->priority > sawwin->priority) + break; + } + } + else { + /* + * Iterate from bottom to top, + * stopping at the first window with equal or higher priority. + */ + fusion_vector_foreach (other, index, sawman->layout) { + D_MAGIC_ASSERT( other, SaWManWindow ); + + if (other->priority >= sawwin->priority) + break; + } + } + + /* (Re)Insert the window at the acquired position. */ + if (sawwin->flags & SWMWF_INSERTED) { + int old = sawman_window_index( sawman, sawwin ); + + D_ASSERT( old >= 0 ); + D_ASSERT( old < sawman->layout.count ); + + if (old < index) + index--; + + if (old != index) { + fusion_vector_move( &sawman->layout, old, index ); + + dfb_wm_dispatch_WindowRestack( layer->core, window, index ); + } + } + else { + ret = fusion_vector_insert( &sawman->layout, sawwin, index ); + if (ret) + return ret; + + dfb_wm_dispatch_WindowRestack( layer->core, window, index ); + + /* Set 'inserted' flag. */ + sawwin->flags |= SWMWF_INSERTED; + + window->flags |= CWF_INSERTED; + + dfb_wm_dispatch_WindowState( layer->core, window ); + } + + return DFB_OK; +} + +DirectResult +sawman_remove_window( SaWMan *sawman, + SaWManWindow *sawwin ) +{ + int index; + CoreWindow *window; + SaWManGrabbedKey *key; + DirectLink *next; + CoreLayer *layer; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + layer = dfb_layer_at( window->stack->context->layer_id ); + + if (!(sawwin->flags & SWMWF_INSERTED)) { + D_BUG( "window %d not inserted", window->id ); + return DFB_BUG; + } + + sawman_withdraw_window( sawman, sawwin ); + + index = sawman_window_index( sawman, sawwin ); + D_ASSERT( index >= 0 ); + D_ASSERT( index < sawman->layout.count ); + + fusion_vector_remove( &sawman->layout, index ); + + /* Release all explicit key grabs. */ + direct_list_foreach_safe (key, next, sawman->grabbed_keys) { + if (key->owner == sawwin) { + direct_list_remove( &sawman->grabbed_keys, &key->link ); + SHFREE( sawwin->shmpool, key ); + } + } + + /* Release grab of unselected keys. */ + if (sawman->unselkeys_window == sawwin) + sawman->unselkeys_window = NULL; + + /* Free key list. */ + if (window->config.keys) { + SHFREE( sawwin->shmpool, window->config.keys ); + + window->config.keys = NULL; + window->config.num_keys = 0; + } + + sawwin->flags &= ~SWMWF_INSERTED; + + window->flags &= ~CWF_INSERTED; + + dfb_wm_dispatch_WindowState( layer->core, window ); + + return DFB_OK; +} + +DirectResult +sawman_withdraw_window( SaWMan *sawman, + SaWManWindow *sawwin ) +{ + int i, index; + CoreWindow *window; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + /* Make sure window is inserted. */ + // NDC - remove the if + // if (!(sawwin->flags & SWMWF_INSERTED)) { + // D_BUG( "window %d not inserted", window->id ); + // } + + /* No longer be the 'entered window'. */ + if (sawman->entered_window == sawwin) + sawman->entered_window = NULL; + + if (sawman->focused_window_to == sawwin) { + sawman->focused_window_to = NULL; + sawman->focused_window_switched = false; + } + + /* Remove focus from window. */ + if (sawman->focused_window == sawwin) { + SaWManWindow *swin; + CoreWindow *cwin; + + sawman_switch_focus( sawman, NULL ); +// sawman->focused_window = NULL; + + /* Always try to have a focused window */ + fusion_vector_foreach_reverse (swin, index, sawman->layout) { + D_MAGIC_ASSERT( swin, SaWManWindow ); + + cwin = swin->window; + D_ASSERT( cwin != NULL ); + + if (swin != sawwin && cwin->config.opacity && !(cwin->config.options & DWOP_GHOST)) { + sawman_switch_focus( sawman, swin ); + break; + } + } + } + +#ifndef OLD_COREWINDOWS_STRUCTURE + if (window->toplevel) { + CoreWindow *toplevel = window->toplevel; + + D_MAGIC_ASSERT( toplevel, CoreWindow ); + + if (toplevel->subfocus == window) + toplevel->subfocus = NULL; + } +#endif + + /* Release explicit keyboard grab. */ + if (sawman->keyboard_window == sawwin) + sawman->keyboard_window = NULL; + + /* Release explicit pointer grab. */ + if (sawman->pointer_window == sawwin) + sawman->pointer_window = NULL; + + /* Release all implicit key grabs. */ + for (i=0; ikeys[i].code != -1 && sawman->keys[i].owner == sawwin) { + if (!DFB_WINDOW_DESTROYED( window )) { + DFBWindowEvent we; + + we.type = DWET_KEYUP; + we.key_code = sawman->keys[i].code; + we.key_id = sawman->keys[i].id; + we.key_symbol = sawman->keys[i].symbol; + + sawman_post_event( sawman, sawwin, &we ); + } + + sawman->keys[i].code = -1; + sawman->keys[i].owner = NULL; + } + } + + /* Hide window. */ + + // NDC but don't for SWMWF_INSERTED windows + if ((sawwin->flags & SWMWF_INSERTED)) { + if (SAWMAN_VISIBLE_WINDOW(window)) { + window->config.opacity = 0; + + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_FORCE_INVISIBLE | SWMUF_UPDATE_BORDER ); + } + } + return DFB_OK; +} + +static void +apply_geometry( const DFBWindowGeometry *geometry, + const DFBRegion *clip, + const DFBWindowGeometry *parent, + DFBRectangle *ret_rect ) +{ + int width, height; + + D_ASSERT( geometry != NULL ); + DFB_REGION_ASSERT( clip ); + D_ASSERT( ret_rect != NULL ); + + width = clip->x2 - clip->x1 + 1; + height = clip->y2 - clip->y1 + 1; + + switch (geometry->mode) { + case DWGM_DEFAULT: + D_DEBUG_AT( SaWMan_Geometry, " -- default\n" ); + *ret_rect = DFB_RECTANGLE_INIT_FROM_REGION( clip ); + D_DEBUG_AT( SaWMan_Geometry, " => %d,%d-%dx%d\n", DFB_RECTANGLE_VALS( ret_rect ) ); + return; + + case DWGM_FOLLOW: + D_ASSERT( parent != NULL ); + D_DEBUG_AT( SaWMan_Geometry, " -- FOLLOW\n" ); + apply_geometry( parent, clip, NULL, ret_rect ); + break; + + case DWGM_RECTANGLE: + D_DEBUG_AT( SaWMan_Geometry, " -- RECTANGLE [%d,%d-%dx%d]\n", + DFB_RECTANGLE_VALS( &geometry->rectangle ) ); + *ret_rect = geometry->rectangle; + ret_rect->x += clip->x1; + ret_rect->y += clip->y1; + break; + + case DWGM_LOCATION: + D_DEBUG_AT( SaWMan_Geometry, " -- LOCATION [%.3f,%.3f-%.3fx%.3f]\n", + geometry->location.x, geometry->location.y, + geometry->location.w, geometry->location.h ); + ret_rect->x = (int)(geometry->location.x * width + 0.5f) + clip->x1; + ret_rect->y = (int)(geometry->location.y * height + 0.5f) + clip->y1; + ret_rect->w = (int)(geometry->location.w * width + 0.5f); + ret_rect->h = (int)(geometry->location.h * height + 0.5f); + break; + + default: + D_BUG( "invalid geometry mode %d", geometry->mode ); + return; + } + + D_DEBUG_AT( SaWMan_Geometry, " -> %d,%d-%dx%d / clip [%d,%d-%dx%d]\n", + DFB_RECTANGLE_VALS( ret_rect ), + DFB_RECTANGLE_VALS_FROM_REGION( clip ) ); + + if (!dfb_rectangle_intersect_by_region( ret_rect, clip )) { + D_WARN( "invalid geometry" ); + dfb_rectangle_from_region( ret_rect, clip ); + } + + D_DEBUG_AT( SaWMan_Geometry, " => %d,%d-%dx%d\n", DFB_RECTANGLE_VALS( ret_rect ) ); +} + +DirectResult +sawman_update_geometry( SaWManWindow *sawwin ) +{ + int i; + CoreWindow *window; + CoreWindow *parent_window = NULL; + CoreWindow *toplevel; + SaWManWindow *topsaw = NULL; + SaWMan *sawman; + SaWManWindow *parent; + SaWManWindow *child; + CoreWindow *childwin; + DFBRegion clip; + DFBRectangle src; + DFBRectangle dst; + bool src_updated = false; + bool dst_updated = false; + + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + D_DEBUG_AT( SaWMan_Geometry, "%s( %p )\n", __FUNCTION__, sawwin ); + + sawman = sawwin->sawman; + D_MAGIC_ASSERT_IF( sawman, SaWMan ); + + if (sawman) + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + parent = sawwin->parent; + if (parent) { + D_MAGIC_ASSERT( parent, SaWManWindow ); + + parent_window = parent->window; + D_ASSERT( parent_window != NULL ); + } + + toplevel = WINDOW_TOPLEVEL(window); + if (toplevel) { + topsaw = toplevel->window_data; + D_MAGIC_ASSERT( topsaw, SaWManWindow ); + } + + if (parent && (window->config.options & DWOP_FOLLOW_BOUNDS)) + /* Initialize bounds from parent window (window association) */ + sawwin->bounds = parent->bounds; + else + /* Initialize bounds from base window configuration */ + sawwin->bounds = window->config.bounds; + + /* + * In case of a sub window, the top level surface is the coordinate space instead of the layer surface + */ + toplevel = WINDOW_TOPLEVEL(window); + if (toplevel) { + DFBDimension in, out; + + D_DEBUG_AT( SaWMan_Geometry, " -> sub bounds %4d,%4d-%4dx%4d (base)\n", DFB_RECTANGLE_VALS(&sawwin->bounds) ); + + D_DEBUG_AT( SaWMan_Geometry, " o- top src %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS(&topsaw->src) ); + D_DEBUG_AT( SaWMan_Geometry, " o- top dst %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS(&topsaw->dst) ); + + /* + * Translate against top level source geometry + */ + sawwin->bounds.x -= topsaw->src.x; + sawwin->bounds.y -= topsaw->src.y; + + D_DEBUG_AT( SaWMan_Geometry, " -> sub bounds %4d,%4d-%4dx%4d (translated)\n", DFB_RECTANGLE_VALS(&sawwin->bounds) ); + + /* + * Take input dimension from top level source geometry + */ + in.w = topsaw->src.w; + in.h = topsaw->src.h; + + /* + * Take output dimension from top level destination geometry + */ + out.w = topsaw->dst.w; + out.h = topsaw->dst.h; + + /* + * Scale the sub window size if top level window is scaled + */ + if (in.w != out.w || in.h != out.h) { + D_DEBUG_AT( SaWMan_Geometry, " o- scale in %4dx%4d\n", in.w, in.h ); + D_DEBUG_AT( SaWMan_Geometry, " o- scale out %4dx%4d\n", out.w, out.h ); + + sawwin->bounds.x = sawwin->bounds.x * out.w / in.w; + sawwin->bounds.y = sawwin->bounds.y * out.h / in.h; + sawwin->bounds.w = sawwin->bounds.w * out.w / in.w; + sawwin->bounds.h = sawwin->bounds.h * out.h / in.h; + + D_DEBUG_AT( SaWMan_Geometry, " -> sub bounds %4d,%4d-%4dx%4d (scaled)\n", DFB_RECTANGLE_VALS(&sawwin->bounds) ); + } + + /* + * Translate to top level destination geometry + */ + sawwin->bounds.x += topsaw->dst.x; + sawwin->bounds.y += topsaw->dst.y; + + D_DEBUG_AT( SaWMan_Geometry, " => sub bounds %4d,%4d-%4dx%4d (translated)\n", DFB_RECTANGLE_VALS(&sawwin->bounds) ); + } + + /* Calculate source geometry. */ + clip.x1 = 0; + clip.y1 = 0; + + if ( (window->caps & (DWCAPS_INPUTONLY | DWCAPS_COLOR)) + || window->config.options & DWOP_INPUTONLY ) { + clip.x2 = sawwin->bounds.w - 1; + clip.y2 = sawwin->bounds.h - 1; + } + else { + CoreSurface *surface = window->surface; + D_ASSERT( surface != NULL ); + + clip.x2 = surface->config.size.w - 1; + clip.y2 = surface->config.size.h - 1; + } + + D_DEBUG_AT( SaWMan_Geometry, " -> Applying source geometry...\n" ); + + apply_geometry( &window->config.src_geometry, &clip, + parent_window ? &parent_window->config.src_geometry : NULL, &src ); + + /* Calculate destination geometry. */ + clip = DFB_REGION_INIT_FROM_RECTANGLE( &sawwin->bounds ); + + D_DEBUG_AT( SaWMan_Geometry, " -> Applying destination geometry...\n" ); + + apply_geometry( &window->config.dst_geometry, &clip, + parent_window ? &parent_window->config.dst_geometry : NULL, &dst ); + + /* Adjust src/dst if clipped by top level window */ + if (toplevel) { + DFBRegion topclip = DFB_REGION_INIT_FROM_RECTANGLE( &topsaw->dst ); + + /* + * Clip the sub window bounds against the top level window + */ + dfb_clip_stretchblit( &topclip, &src, &dst ); + + D_DEBUG_AT( SaWMan_Geometry, " => sub dst %4d,%4d-%4dx%4d (clipped)\n", DFB_RECTANGLE_VALS(&dst) ); + D_DEBUG_AT( SaWMan_Geometry, " => sub src %4d,%4d-%4dx%4d (clipped)\n", DFB_RECTANGLE_VALS(&src) ); + } + + /* Update source geometry. */ + if (!DFB_RECTANGLE_EQUAL( src, sawwin->src )) { + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_NONE ); + + sawwin->src = src; + src_updated = true; + } + + /* Update destination geometry. */ + if (!DFB_RECTANGLE_EQUAL( dst, sawwin->dst )) { + if (!src_updated) + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_NONE ); + + sawwin->dst = dst; + dst_updated = true; + + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_NONE ); + } + + D_DEBUG_AT( SaWMan_Geometry, " -> Updating children (associated windows)...\n" ); + + fusion_vector_foreach (child, i, sawwin->children) { + D_MAGIC_ASSERT( child, SaWManWindow ); + + childwin = child->window; + D_ASSERT( childwin != NULL ); + + if ((childwin->config.src_geometry.mode == DWGM_FOLLOW && src_updated) || + (childwin->config.dst_geometry.mode == DWGM_FOLLOW && dst_updated) || + (childwin->config.options & DWOP_FOLLOW_BOUNDS)) + sawman_update_geometry( child ); + } + +#ifndef OLD_COREWINDOWS_STRUCTURE + D_DEBUG_AT( SaWMan_Geometry, " -> Updating children (sub windows)...\n" ); + + fusion_vector_foreach (childwin, i, window->subwindows) { + D_ASSERT( childwin != NULL ); + + sawman_update_geometry( childwin->window_data ); + } +#endif + + return DFB_OK; +} + +DirectResult +sawman_set_opacity( SaWMan *sawman, + SaWManWindow *sawwin, + u8 opacity ) +{ + u8 old; + StackData *data; + CoreWindowStack *stack; + CoreWindow *window; + + D_DEBUG_AT( SaWMan_Focus, "%s( %p, sawwin %p, opacity 0x%02x )\n", __FUNCTION__, sawman, sawwin, opacity ); + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_ASSERT( sawwin->stack_data != NULL ); + D_ASSERT( sawwin->stack != NULL ); + D_ASSERT( sawwin->window != NULL ); + + data = sawwin->stack_data; + stack = sawwin->stack; + window = sawwin->window; + old = window->config.opacity; + + if (!dfb_config->translucent_windows && opacity) { + D_DEBUG_AT( SaWMan_Focus, " -> forcing to 0xff\n" ); + + opacity = 0xFF; + } + + if (old != opacity) { + window->config.opacity = opacity; + + if (sawwin->flags & SWMWF_INSERTED) { + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_FORCE_INVISIBLE | SWMUF_UPDATE_BORDER ); + + /* Ungrab pointer/keyboard, pass focus... */ + if (old && !opacity) { + D_DEBUG_AT( SaWMan_Focus, " -> hiding window... (focused %p)\n", sawman->focused_window ); + + /* Possibly switch focus to window now under the cursor */ + if (sawman->focused_window == sawwin) { + D_DEBUG_AT( SaWMan_Focus, " -> updating focus\n" ); + + sawman_update_focus( data->sawman, data->stack, data->stack->cursor.x, data->stack->cursor.y ); + } + + D_DEBUG_AT( SaWMan_Focus, " -> withdrawing window...\n" ); + + sawman_withdraw_window( sawman, sawwin ); + } + } + else + D_DEBUG_AT( SaWMan_Focus, " -> not inserted\n" ); + } + else + D_DEBUG_AT( SaWMan_Focus, " -> no change\n" ); + + return DFB_OK; +} + +DirectResult +sawman_window_set_cursor_flags( SaWMan *sawman, + SaWManWindow *sawwin, + DFBWindowCursorFlags flags ) +{ + StackData *data; + CoreWindowStack *stack; + CoreWindow *window; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_ASSERT( sawwin->stack_data != NULL ); + D_ASSERT( sawwin->stack != NULL ); + D_ASSERT( sawwin->window != NULL ); + + data = sawwin->stack_data; + stack = sawwin->stack; + window = sawwin->window; + + if (window->config.cursor_flags != flags) { + window->config.cursor_flags = flags; + + if (sawwin == sawman->focused_window) + sawman_window_apply_cursor_flags( sawman, sawwin ); + } + + return DFB_OK; +} + +DirectResult +sawman_window_apply_cursor_flags( SaWMan *sawman, + SaWManWindow *sawwin ) +{ + StackData *data; + CoreWindowStack *stack; + CoreWindow *window; + CoreCursorUpdateFlags update = CCUF_NONE; + u8 opacity; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_ASSERT( sawwin->stack_data != NULL ); + D_ASSERT( sawwin->stack != NULL ); + D_ASSERT( sawwin->window != NULL ); + + data = sawwin->stack_data; + stack = sawwin->stack; + window = sawwin->window; + + D_DEBUG_AT( SaWMan_Cursor, "%s( %p, flags 0x%04x )\n", __FUNCTION__, sawwin, window->config.cursor_flags ); + + opacity = (window->config.cursor_flags & DWCF_INVISIBLE) ? 0x00 : 0xff; + + D_DEBUG_AT( SaWMan_Cursor, " -> opacity %d\n", opacity ); + + if (!(window->config.cursor_flags & DWCF_UNCLIPPED)) { + int cx = stack->cursor.x; + int cy = stack->cursor.y; + + if (cx < 0) + cx = 0; + else if (cx >= sawman->resolution.w) + cx = sawman->resolution.w - 1; + + if (cy < 0) + cy = 0; + else if (cy >= sawman->resolution.h) + cy = sawman->resolution.h - 1; + + if (cx != stack->cursor.x || cy != stack->cursor.y) { + D_DEBUG_AT( SaWMan_Cursor, " -> Cursor clipped %d,%d -> %d,%d\n", + stack->cursor.x, stack->cursor.y, cx, cy ); + printf( "===JK sawman -> Cursor clipped %d,%d -> %d,%d\n", + stack->cursor.x, stack->cursor.y, cx, cy ); + + stack->cursor.x = cx; + stack->cursor.y = cy; + + update |= CCUF_POSITION; + } + } + + if (stack->cursor.opacity != opacity) { + stack->cursor.opacity = opacity; + + update |= CCUF_OPACITY; + } + + D_DEBUG_AT( SaWMan_Cursor, " -> update 0x%04x\n", update ); + + if (update) + dfb_wm_update_cursor( stack, update ); + + return DFB_OK; +} + +bool +sawman_update_focus( SaWMan *sawman, + CoreWindowStack *stack, + int x, + int y ) +{ + StackData *data; + + D_DEBUG_AT( SaWMan_Focus, "%s( %p, stack %p, xy %d,%d )\n", __FUNCTION__, sawman, stack, x, y ); + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( stack != NULL ); + + data = stack->stack_data; + + D_MAGIC_ASSERT( data, StackData ); + + /* if pointer is not grabbed */ + if (!sawman->pointer_window) { + SaWManWindow *before = sawman->entered_window; + SaWManWindow *after = sawman_window_at_pointer( sawman, stack, x, y ); + + /* and the window under the cursor is another one now */ + if (before != after) { + DFBWindowEvent we; + + /* send leave event */ + if (before) { + D_MAGIC_ASSERT( before, SaWManWindow ); + D_ASSERT( before->window != NULL ); + + we.type = DWET_LEAVE; + + sawman_window_get_cursor_position( sawman, stack, before, &we.x, &we.y, &we.cx, &we.cy ); + + sawman_post_event( sawman, before, &we ); + } + + /* switch focus and send enter event */ + sawman_switch_focus( sawman, after ); + + if (after) { + D_MAGIC_ASSERT( after, SaWManWindow ); + D_ASSERT( after->window != NULL ); + + we.type = DWET_ENTER; + + sawman_window_get_cursor_position( sawman, stack, after, &we.x, &we.y, &we.cx, &we.cy ); + + sawman_post_event( sawman, after, &we ); + } + + /* update pointer to window under the cursor */ + sawman->entered_window = after; + + return true; + } + } + + return false; +} + + +DFBResult +sawman_restack_window( SaWMan *sawman, + SaWManWindow *sawwin, + SaWManWindow *relative, + int relation, + DFBWindowStackingClass stacking ) +{ + int i; + int old; + int index; + int priority; + StackData *data; + SaWManWindow *tmpsaw; + CoreWindow *window; + CoreLayer *layer; + +#ifndef OLD_COREWINDOWS_STRUCTURE + int n; + CoreWindow *tmp; +#endif + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_MAGIC_ASSERT_IF( relative, SaWManWindow ); + D_ASSERT( sawwin->stack_data != NULL ); + + D_ASSERT( relative == NULL || relative == sawwin || relation != 0); + + D_DEBUG_AT( SaWMan_Stacking, "%s( %p, %p, %p, %d, 0x%d )\n", __FUNCTION__, + sawman, sawwin, relative, relation, stacking ); + + data = sawwin->stack_data; + window = sawwin->window; + + D_ASSERT( window != NULL ); + + layer = dfb_layer_at( window->stack->context->layer_id ); + + /* Change stacking class. */ + if (stacking != window->config.stacking) { + window->config.stacking = stacking; + + sawwin->priority = sawman_window_priority( sawwin ); + } + + /* Make sure window is inserted and not kept above/under parent. */ + if (!(sawwin->flags & SWMWF_INSERTED) || (window->config.options & (DWOP_KEEP_ABOVE|DWOP_KEEP_UNDER))) + return DFB_OK; + + /* Get the (new) priority. */ + priority = sawwin->priority; + +#ifndef OLD_COREWINDOWS_STRUCTURE + /* In case of a sub window, the sub window vector is modified and the window reinserted */ + if (window->toplevel) { + CoreWindow *toplevel = window->toplevel; + + /* Get the old index. */ + old = fusion_vector_index_of( &toplevel->subwindows, window ); + D_ASSERT( old >= 0 ); + + D_DEBUG_AT( SaWMan_Stacking, " -> old sub index %d\n", old ); + + /* Calculate the desired index. */ + if (relative) { + index = fusion_vector_index_of( &toplevel->subwindows, relative->window ); + if (index < 0) + return DFB_INVARG; + + 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 > toplevel->subwindows.count - 1) + index = toplevel->subwindows.count - 1; + } + else if (relation) + index = toplevel->subwindows.count - 1; + else + index = 0; + + D_DEBUG_AT( SaWMan_Stacking, " -> new sub index %d\n", index ); + + if (relation < 0) { + while (index > 0) { + SaWManWindow *other = fusion_vector_at( &toplevel->subwindows, index ); + SaWManWindow *under = fusion_vector_at( &toplevel->subwindows, index - 1 ); + + D_MAGIC_ASSERT( other, SaWManWindow ); + D_MAGIC_ASSERT( under, SaWManWindow ); + + if ((other->window->config.options & DWOP_KEEP_ABOVE) || + (under->window->config.options & DWOP_KEEP_UNDER)) + index--; + else + break; + } + } + else if (relation > 0) { + while (index < toplevel->subwindows.count - 1) { + SaWManWindow *other = fusion_vector_at( &toplevel->subwindows, index ); + SaWManWindow *above = fusion_vector_at( &toplevel->subwindows, index + 1 ); + + D_MAGIC_ASSERT( other, SaWManWindow ); + D_MAGIC_ASSERT( above, SaWManWindow ); + + if ((above->window->config.options & DWOP_KEEP_ABOVE) || + (other->window->config.options & DWOP_KEEP_UNDER)) + index++; + else + break; + } + } + + D_DEBUG_AT( SaWMan_Stacking, " -> new sub index %d\n", index ); + + /* Return if index hasn't changed. */ + if (index == old) + return DFB_OK; + + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + + /* Actually change the stacking order now. */ + fusion_vector_move( &toplevel->subwindows, old, index ); + + /* Reinsert to move in layout as well. */ + sawman_insert_window( sawman, sawwin, NULL, false ); + + /* Reinsert associated windows to ensure above/under rules apply. */ + fusion_vector_foreach (tmpsaw, i, sawwin->children) { + if (tmpsaw->window->config.options & (DWOP_KEEP_ABOVE|DWOP_KEEP_UNDER)) { + sawman_update_window( sawman, tmpsaw, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + sawman_insert_window( sawman, tmpsaw, NULL, false ); + sawman_update_window( sawman, tmpsaw, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + } + } + } + else +#endif + { + /* Get the old index. */ + old = sawman_window_index( sawman, sawwin ); + D_ASSERT( old >= 0 ); + + D_DEBUG_AT( SaWMan_Stacking, " -> old index %d\n", old ); + + /* Calculate the desired index. */ + if (relative) { + index = sawman_window_index( sawman, relative ); + + if (relation > 0) { + if (old < index) + index--; + } + else if (relation < 0) { + if (old > index) + index++; + } + + index += relation; + + if (relation > 0) + index += WINDOW_SUBWINDOWS_COUNT(window); + + if (index < 0) + index = 0; + else if (index > sawman->layout.count - 1) + index = sawman->layout.count - 1; + } + else if (relation) + index = sawman->layout.count - 1; + else + index = 0; + + D_DEBUG_AT( SaWMan_Stacking, " -> new index %d\n", index ); + + /* Assure window won't be above any window with a higher priority. */ + while (index > 0) { + int below = (old < index) ? index : index - 1; + SaWManWindow *other = fusion_vector_at( &sawman->layout, below ); + + D_MAGIC_ASSERT( other, SaWManWindow ); + + if (priority < other->priority) + index--; + else + break; + } + + D_DEBUG_AT( SaWMan_Stacking, " -> new index %d\n", index ); + + /* Assure window won't be below any window with a lower priority. */ + while (index < sawman->layout.count - 1) { + int above = (old > index) ? index : index + 1; + SaWManWindow *other = fusion_vector_at( &sawman->layout, above ); + + D_MAGIC_ASSERT( other, SaWManWindow ); + + if (priority > other->priority) + index++; + else + break; + } + + D_DEBUG_AT( SaWMan_Stacking, " -> new index %d\n", index ); + + if (relation < 0) { + /* Assure window won't be below a sub window (getting between sub and top or other sub window) */ + while (index > 0) { + SaWManWindow *other = fusion_vector_at( &sawman->layout, index ); + SaWManWindow *under = fusion_vector_at( &sawman->layout, index - 1 ); + + D_MAGIC_ASSERT( other, SaWManWindow ); + D_MAGIC_ASSERT( under, SaWManWindow ); + + if (WINDOW_TOPLEVEL(other->window) || + (other->window->config.options & DWOP_KEEP_ABOVE) || + (under->window->config.options & DWOP_KEEP_UNDER)) + index--; + else + break; + } + } + else if (relation > 0) { + /* Assure window won't be below a sub window (getting between sub and top or other sub window) */ + while (index < sawman->layout.count - 1) { + SaWManWindow *other = fusion_vector_at( &sawman->layout, index ); + SaWManWindow *above = fusion_vector_at( &sawman->layout, index + 1 ); + + D_MAGIC_ASSERT( other, SaWManWindow ); + D_MAGIC_ASSERT( above, SaWManWindow ); + + if (WINDOW_TOPLEVEL(above->window) || + (above->window->config.options & DWOP_KEEP_ABOVE) || + (other->window->config.options & DWOP_KEEP_UNDER)) + index++; + else + break; + } + } + + D_DEBUG_AT( SaWMan_Stacking, " -> new index %d\n", index ); + + /* Return if index hasn't changed. */ + if (index == old) + return DFB_OK; + + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + + /* Actually change the stacking order now. */ + fusion_vector_move( &sawman->layout, old, index ); + + D_DEBUG_AT( SaWMan_Stacking, " -> now index %d\n", fusion_vector_index_of( &sawman->layout, sawwin ) ); + + dfb_wm_dispatch_WindowRestack( layer->core, window, index ); + +#ifndef OLD_COREWINDOWS_STRUCTURE + /* Reinsert sub windows to ensure they're in order (above top level). */ + fusion_vector_foreach (tmp, i, window->subwindows) { + sawman_update_window( sawman, tmp->window_data, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + sawman_insert_window( sawman, tmp->window_data, NULL, false ); + sawman_update_window( sawman, tmp->window_data, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + } +#endif + + /* Reinsert associated windows to ensure above/under rules apply. */ + fusion_vector_foreach (tmpsaw, i, sawwin->children) { + if (tmpsaw->window->config.options & (DWOP_KEEP_ABOVE|DWOP_KEEP_UNDER)) { + sawman_update_window( sawman, tmpsaw, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + sawman_insert_window( sawman, tmpsaw, NULL, false ); + sawman_update_window( sawman, tmpsaw, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + +#ifndef OLD_COREWINDOWS_STRUCTURE + /* Reinsert sub windows to ensure they're in order (above top level). */ + fusion_vector_foreach (tmp, n, tmpsaw->window->subwindows) { + sawman_update_window( sawman, tmp->window_data, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + sawman_insert_window( sawman, tmp->window_data, NULL, false ); + sawman_update_window( sawman, tmp->window_data, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + } +#endif + } + } + } + + sawman_update_window( sawman, sawwin, NULL, DSFLIP_NONE, SWMUF_UPDATE_BORDER ); + + return DFB_OK; +} + + +SaWManWindow* +sawman_window_at_pointer( SaWMan *sawman, + CoreWindowStack *stack, + int x, + int y ) +{ + int i; + SaWManWindow *sawwin; + CoreWindow *window; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( stack != NULL ); + + if (!stack->cursor.enabled) { + fusion_vector_foreach_reverse (sawwin, i, sawman->layout) { + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + window = sawwin->window; + D_ASSERT( window != NULL ); + + if (window->config.opacity && !(window->config.options & DWOP_GHOST)) + return sawwin; + } + + return NULL; + } + + if (x < 0) + x = stack->cursor.x; + if (y < 0) + y = stack->cursor.y; + + fusion_vector_foreach_reverse (sawwin, i, sawman->layout) { + SaWManTier *tier; + int tx, ty; + + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + window = sawwin->window; + D_ASSERT( window != NULL ); + + /* Retrieve corresponding SaWManTier. */ + tier = sawman_tier_by_class( sawman, sawwin->window->config.stacking ); + D_MAGIC_ASSERT( tier, SaWManTier ); + + /* Convert to Tier coordinates */ + tx = (s64) x * (s64) tier->size.w / (s64) sawman->resolution.w; + ty = (s64) y * (s64) tier->size.h / (s64) sawman->resolution.h; + + if (!(window->config.options & DWOP_GHOST) && window->config.opacity && + tx >= sawwin->bounds.x && tx < sawwin->bounds.x + sawwin->bounds.w && + ty >= sawwin->bounds.y && ty < sawwin->bounds.y + sawwin->bounds.h) + return sawwin; + } + + return NULL; +} + +void +sawman_window_get_cursor_position( SaWMan *sawman, + CoreWindowStack *stack, + SaWManWindow *sawwin, + int *ret_x, + int *ret_y, + int *ret_cx, + int *ret_cy ) +{ + int x, y; + int cx, cy; + int sx, sy; + SaWManTier *tier; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_ASSERT( stack != NULL ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_ASSERT( sawwin->window != NULL ); + + /* Retrieve corresponding SaWManTier. */ + tier = sawman_tier_by_class( sawman, sawwin->window->config.stacking ); + D_MAGIC_ASSERT( tier, SaWManTier ); + + x = stack->cursor.x; + y = stack->cursor.y; + + /* Convert to Tier coordinates */ + cx = (s64) x * (s64) tier->size.w / (s64) sawman->resolution.w; + cy = (s64) y * (s64) tier->size.h / (s64) sawman->resolution.h; + + /* Subtract offset of Window within layout (tier coordinates) */ + x = cx - sawwin->dst.x; + y = cy - sawwin->dst.y; + + /* Convert to Window coordinates */ + sx = sawwin->window->config.cursor_resolution.w ?: sawwin->src.w; + sy = sawwin->window->config.cursor_resolution.h ?: sawwin->src.h; + + x = x * sx / sawwin->dst.w; + y = y * sy / sawwin->dst.h; + + cx = cx * sx / sawwin->dst.w; + cy = cy * sy / sawwin->dst.h; + + if (ret_x) + *ret_x = x; + + if (ret_y) + *ret_y = y; + + if (ret_cx) + *ret_cx = cx; + + if (ret_cy) + *ret_cy = cy; + + D_INFO( "%d,%d - %d,%d\n",x,y,cx,cy); +} + +int +sawman_window_border( const SaWManWindow *sawwin ) +{ + SaWMan *sawman; + const CoreWindow *window; + const SaWManTier *tier; + const SaWManBorderInit *border; + int thickness = 0; + + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + sawman = sawwin->sawman; + D_MAGIC_ASSERT( sawman, SaWMan ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + if (sawwin->caps & DWCAPS_NODECORATION) + return 0; + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + tier = sawman_tier_by_class( sawwin->sawman, window->config.stacking ); + D_MAGIC_ASSERT( tier, SaWManTier ); + + D_ASSERT( sawman_config != NULL ); + + border = &sawman_config->borders[sawman_window_priority(sawwin)]; + + thickness = border->thickness; + if (thickness && border->resolution.w && border->resolution.h) { + if (border->resolution.w != tier->size.w && border->resolution.h != tier->size.h) { + int tw = thickness * tier->size.w / border->resolution.w; + int th = thickness * tier->size.h / border->resolution.h; + + thickness = (tw + th + 1) / 2; + } + } + + return thickness; +} + +/**********************************************************************************************************************/ + +/* + skipping opaque windows that are above the window that changed +*/ +static void +wind_of_change( SaWMan *sawman, + SaWManTier *tier, + DFBRegion *update, + DFBSurfaceFlipFlags flags, + int current, + int changed ) +{ + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( tier, SaWManTier ); + D_ASSERT( update != NULL ); + + /* + loop through windows above + */ + for (; current > changed; current--) { + CoreWindow *window; + SaWManWindow *sawwin; + DFBRegion opaque; + DFBWindowOptions options; + + D_ASSERT( changed >= 0 ); + D_ASSERT( current >= changed ); + D_ASSERT( current < fusion_vector_size( &sawman->layout ) ); + + sawwin = fusion_vector_at( &sawman->layout, current ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + options = window->config.options; + + D_DEBUG_AT( SaWMan_Update, "--[%p] %4d,%4d-%4dx%4d : %d->%d\n", + tier, DFB_RECTANGLE_VALS_FROM_REGION( update ), current, changed ); + + /* + can skip opaque region + */ + if ((tier->classes & (1 << window->config.stacking)) && ( ( + //can skip all opaque window? + (window->config.opacity == 0xff) && + !(window->caps & DWCAPS_INPUTONLY) && + !(options & (DWOP_INPUTONLY | DWOP_COLORKEYING | DWOP_ALPHACHANNEL)) && + (opaque=*update,dfb_region_intersect( &opaque, + sawwin->dst.x, sawwin->dst.y, + sawwin->dst.x + sawwin->dst.w - 1, + sawwin->dst.y + sawwin->dst.h - 1 ) ) + )||( + //can skip opaque region? + (options & DWOP_ALPHACHANNEL) && + (options & DWOP_OPAQUE_REGION) && + (window->config.opacity == 0xff) && + !(options & DWOP_COLORKEYING) && + (opaque=*update,dfb_region_intersect( &opaque, /* FIXME: Scaling */ + sawwin->dst.x + window->config.opaque.x1, + sawwin->dst.y + window->config.opaque.y1, + sawwin->dst.x + window->config.opaque.x2, + sawwin->dst.y + window->config.opaque.y2 )) + ) )) + { + /* left */ + if (opaque.x1 != update->x1) { + DFBRegion left = { update->x1, opaque.y1, opaque.x1-1, opaque.y2}; + wind_of_change( sawman, tier, &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( sawman, tier, &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( sawman, tier, &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( sawman, tier, &lower, flags, current-1, changed ); + } + + return; + } + } + + D_DEBUG_AT( SaWMan_Update, "+ UPDATE %4d,%4d-%4dx%4d\n", + DFB_RECTANGLE_VALS_FROM_REGION( update ) ); + + dfb_updates_add( &tier->updates, update ); +} + +static void +wind_of_showing( SaWMan *sawman, + SaWManTier *tier, + DFBRegion *update, + int current, + int changed, + bool *ret_showing ) +{ + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( tier, SaWManTier ); + D_ASSERT( update != NULL ); + + if (*ret_showing) + return; + + /* + loop through windows above + */ + for (; current > changed; current--) { + CoreWindow *window; + SaWManWindow *sawwin; + DFBRegion opaque; + DFBWindowOptions options; + + D_ASSERT( changed >= 0 ); + D_ASSERT( current >= changed ); + D_ASSERT( current < fusion_vector_size( &sawman->layout ) ); + + sawwin = fusion_vector_at( &sawman->layout, current ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + options = window->config.options; + + /* + can skip opaque region + */ + if ((tier->classes & (1 << window->config.stacking)) && ( ( + //can skip all opaque window? + (window->config.opacity == 0xff) && + !(options & (DWOP_COLORKEYING | DWOP_ALPHACHANNEL)) && + (opaque=*update,dfb_region_intersect( &opaque, + sawwin->dst.x, sawwin->dst.y, + sawwin->dst.x + sawwin->dst.w - 1, + sawwin->dst.y + sawwin->dst.h - 1 ) ) + )||( + //can skip opaque region? + (options & DWOP_ALPHACHANNEL) && + (options & DWOP_OPAQUE_REGION) && + (window->config.opacity == 0xff) && + !(options & DWOP_COLORKEYING) && + (opaque=*update,dfb_region_intersect( &opaque, /* FIXME: Scaling */ + sawwin->dst.x + window->config.opaque.x1, + sawwin->dst.y + window->config.opaque.y1, + sawwin->dst.x + window->config.opaque.x2, + sawwin->dst.y + window->config.opaque.y2 )) + ) )) + { + /* left */ + if (opaque.x1 != update->x1) { + DFBRegion left = { update->x1, opaque.y1, opaque.x1-1, opaque.y2}; + wind_of_showing( sawman, tier, &left, current-1, changed, ret_showing ); + } + /* upper */ + if (opaque.y1 != update->y1) { + DFBRegion upper = { update->x1, update->y1, update->x2, opaque.y1-1}; + wind_of_showing( sawman, tier, &upper, current-1, changed, ret_showing ); + } + /* right */ + if (opaque.x2 != update->x2) { + DFBRegion right = { opaque.x2+1, opaque.y1, update->x2, opaque.y2}; + wind_of_showing( sawman, tier, &right, current-1, changed, ret_showing ); + } + /* lower */ + if (opaque.y2 != update->y2) { + DFBRegion lower = { update->x1, opaque.y2+1, update->x2, update->y2}; + wind_of_showing( sawman, tier, &lower, current-1, changed, ret_showing ); + } + + return; + } + } + + *ret_showing = true; +} + +static void +update_region( SaWMan *sawman, + SaWManTier *tier, + CardState *state, + int start, + int x1, + int y1, + int x2, + int y2 ) +{ + int i = start; + DFBRegion region = { x1, y1, x2, y2 }; + CoreWindow *window = NULL; + SaWManWindow *sawwin = NULL; + + D_DEBUG_AT( SaWMan_Update, "%s( %p, %d, %d,%d - %d,%d )\n", __FUNCTION__, tier, start, x1, y1, x2, y2 ); + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( tier, SaWManTier ); + D_MAGIC_ASSERT( state, CardState ); + D_ASSERT( start < fusion_vector_size( &sawman->layout ) ); + D_ASSUME( x1 <= x2 ); + D_ASSUME( y1 <= y2 ); + + if (x1 > x2 || y1 > y2) + return; + + /* Find next intersecting window. */ + while (i >= 0) { + sawwin = fusion_vector_at( &sawman->layout, i ); + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + if (SAWMAN_VISIBLE_WINDOW( window ) && (tier->classes & (1 << window->config.stacking))) { + if (dfb_region_intersect( ®ion, + DFB_REGION_VALS_FROM_RECTANGLE( &sawwin->bounds ))) + break; + } + + i--; + } + + /* Intersecting window found? */ + if (i >= 0) { + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + D_MAGIC_COREWINDOW_ASSERT( window ); + + if (D_FLAGS_ARE_SET( window->config.options, DWOP_ALPHACHANNEL | DWOP_OPAQUE_REGION )) { + DFBRegion opaque = DFB_REGION_INIT_TRANSLATED( &window->config.opaque, + sawwin->bounds.x, + sawwin->bounds.y ); + + if (!dfb_region_region_intersect( &opaque, ®ion )) { + update_region( sawman, tier, state, i-1, x1, y1, x2, y2 ); + + sawman_draw_window( tier, sawwin, state, ®ion, true ); + } + else { + if ((window->config.opacity < 0xff) || (window->config.options & DWOP_COLORKEYING)) { + /* draw everything below */ + update_region( sawman, tier, state, i-1, x1, y1, x2, y2 ); + } + else { + /* left */ + if (opaque.x1 != x1) + update_region( sawman, tier, state, i-1, x1, opaque.y1, opaque.x1-1, opaque.y2 ); + + /* upper */ + if (opaque.y1 != y1) + update_region( sawman, tier, state, i-1, x1, y1, x2, opaque.y1-1 ); + + /* right */ + if (opaque.x2 != x2) + update_region( sawman, tier, state, i-1, opaque.x2+1, opaque.y1, x2, opaque.y2 ); + + /* lower */ + if (opaque.y2 != y2) + update_region( sawman, tier, 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 }; + sawman_draw_window( tier, sawwin, state, &r, true ); + } + + /* upper */ + if (opaque.y1 != region.y1) { + DFBRegion r = { region.x1, region.y1, region.x2, opaque.y1 - 1 }; + sawman_draw_window( tier, sawwin, state, &r, true ); + } + + /* right */ + if (opaque.x2 != region.x2) { + DFBRegion r = { opaque.x2 + 1, opaque.y1, region.x2, opaque.y2 }; + sawman_draw_window( tier, sawwin, state, &r, true ); + } + + /* lower */ + if (opaque.y2 != region.y2) { + DFBRegion r = { region.x1, opaque.y2 + 1, region.x2, region.y2 }; + sawman_draw_window( tier, sawwin, state, &r, true ); + } + + /* inner */ + sawman_draw_window( tier, sawwin, state, &opaque, false ); + } + } + else { + if (SAWMAN_TRANSLUCENT_WINDOW( window )) { + /* draw everything below */ + update_region( sawman, tier, state, i-1, x1, y1, x2, y2 ); + } + else { + DFBRegion dst = DFB_REGION_INIT_FROM_RECTANGLE( &sawwin->dst ); + + dfb_region_region_intersect( &dst, ®ion ); + + /* left */ + if (dst.x1 != x1) + update_region( sawman, tier, state, i-1, x1, dst.y1, dst.x1-1, dst.y2 ); + + /* upper */ + if (dst.y1 != y1) + update_region( sawman, tier, state, i-1, x1, y1, x2, dst.y1-1 ); + + /* right */ + if (dst.x2 != x2) + update_region( sawman, tier, state, i-1, dst.x2+1, dst.y1, x2, dst.y2 ); + + /* lower */ + if (dst.y2 != y2) + update_region( sawman, tier, state, i-1, x1, dst.y2+1, x2, y2 ); + } + + sawman_draw_window( tier, sawwin, state, ®ion, true ); + } + } + else + sawman_draw_background( tier, state, ®ion ); +} + +static void +repaint_tier( SaWMan *sawman, + SaWManTier *tier, + const DFBRegion *updates, + int num_updates, + DFBSurfaceFlipFlags flags ) +{ + int i; + CoreLayer *layer; + CoreLayerRegion *region; + CardState *state; + CoreSurface *surface; + DFBRegion cursor_inter; + CoreWindowStack *stack; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( tier, SaWManTier ); + D_ASSERT( updates != NULL ); + D_ASSERT( num_updates > 0 ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + stack = tier->stack; + D_ASSERT( stack != NULL ); + + region = tier->region; + D_ASSERT( region != NULL ); + + layer = dfb_layer_at( tier->layer_id ); + state = &layer->state; + surface = region->surface; + + if (/*!data->active ||*/ !surface) + return; + + D_DEBUG_AT( SaWMan_Update, "%s( %p, %p )\n", __FUNCTION__, sawman, tier ); + + /* Set destination. */ + state->destination = surface; + state->modified |= SMF_DESTINATION; + + for (i=0; i %d, %d - %dx%d (%d)\n", + DFB_RECTANGLE_VALS_FROM_REGION( update ), i ); + + dfb_state_set_dst_colorkey( state, dfb_color_to_pixel( region->config.format, + region->config.src_key.r, + region->config.src_key.g, + region->config.src_key.b ) ); + + /* Set clipping region. */ + dfb_state_set_clip( state, update ); + + /* Compose updated region. */ + update_region( sawman, tier, state, + fusion_vector_size( &sawman->layout ) - 1, + update->x1, update->y1, update->x2, update->y2 ); + + /* Update cursor? */ + cursor_inter = tier->cursor_region; + if (tier->cursor_drawn && dfb_region_region_intersect( &cursor_inter, update )) { + int x, y; + DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &cursor_inter ); + + D_ASSUME( tier->cursor_bs_valid ); + + dfb_gfx_copy_to( surface, tier->cursor_bs, &rect, + rect.x - tier->cursor_region.x1, + rect.y - tier->cursor_region.y1, true ); + + x = (s64) stack->cursor.x * (s64) tier->size.w / (s64) sawman_config->resolution.w; + y = (s64) stack->cursor.y * (s64) tier->size.h / (s64) sawman_config->resolution.h; + + sawman_draw_cursor( stack, state, &cursor_inter, x, y ); + + } + } + + /* 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; ilock )) + return; + + buffer = dfb_surface_get_buffer( surface, CSBR_FRONT ); + D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); + + ret = dfb_surface_buffer_dump( buffer, "/", "tier" ); + + fusion_skirmish_dismiss( &surface->lock ); + } +#endif + + if (1) { + SaWManTierUpdate update; + + direct_memcpy( &update.regions[0], updates, sizeof(DFBRegion) * num_updates ); + + update.num_regions = num_updates; + + fusion_reactor_dispatch_channel( tier->reactor, SAWMAN_TIER_UPDATE, &update, sizeof(update), true, NULL ); + } +} + +static SaWManWindow * +get_single_window( SaWMan *sawman, + SaWManTier *tier, + bool *ret_none ) +{ + int n; + SaWManWindow *sawwin; + SaWManWindow *single = NULL; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( tier, SaWManTier ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + fusion_vector_foreach_reverse (sawwin, n, sawman->layout) { + CoreWindow *window; + + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + if (SAWMAN_VISIBLE_WINDOW(window) && (tier->classes & (1 << window->config.stacking))) { + if ( single + || ( window->caps & (DWCAPS_INPUTONLY | DWCAPS_COLOR) ) + || ( window->config.options & DWOP_INPUTONLY ) ) + return NULL; + + single = sawwin; + + if (single->dst.x == 0 && + single->dst.y == 0 && + single->dst.w == tier->size.w && + single->dst.h == tier->size.h && + !SAWMAN_TRANSLUCENT_WINDOW(window)) + break; + } + } + + if (ret_none && !single) + *ret_none = true; + + return single; +} + +static bool +get_border_only( SaWMan *sawman, + SaWManTier *tier ) +{ + int n; + SaWManWindow *sawwin; + bool none = true; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( tier, SaWManTier ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + fusion_vector_foreach_reverse (sawwin, n, sawman->layout) { + CoreWindow *window; + + D_MAGIC_ASSERT( sawwin, SaWManWindow ); + + window = sawwin->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + none = false; + + if ( SAWMAN_VISIBLE_WINDOW(window) + && !(window->caps & DWCAPS_INPUTONLY) + && !(window->config.options & DWOP_INPUTONLY) ) + return false; + } + + return !none; +} + +static bool +windows_updating( SaWMan *sawman, + SaWManTier *tier ) +{ + int i; + SaWManWindow *window; + + D_MAGIC_ASSERT( sawman, SaWMan ); + D_MAGIC_ASSERT( tier, SaWManTier ); + + fusion_vector_foreach (window, i, sawman->layout) { + D_MAGIC_ASSERT( window, SaWManWindow ); + + if (window->flags & SWMWF_UPDATING) { + long long diff = direct_clock_get_millis() - window->update_ms; + + if (!sawman_config->flip_once_timeout || diff < sawman_config->flip_once_timeout) { + D_DEBUG_AT( SaWMan_FlipOnce, " -> update blocking on window id %u (%lld ms, flags 0x%08x)\n", + window->id, diff, window->flags ); + + return true; + } + + D_DEBUG_AT( SaWMan_FlipOnce, " -> ignoring blocking of window id %u (%lld ms, flags 0x%08x)\n", + window->id, diff, window->flags ); + } + } + + D_DEBUG_AT( SaWMan_FlipOnce, " -> update not blocked by any window\n" ); + + return false; +} + +/* FIXME: Split up in smaller functions and clean up things like forcing reconfiguration. */ +DirectResult +sawman_process_updates( SaWMan *sawman, + DFBSurfaceFlipFlags flags ) +{ + DirectResult ret; + int idx = -1; + SaWManTier *tier; + + D_MAGIC_ASSERT( sawman, SaWMan ); + FUSION_SKIRMISH_ASSERT( &sawman->lock ); + + D_DEBUG_AT( SaWMan_Update, "%s( %p, 0x%08x )\n", __FUNCTION__, sawman, flags ); + + if (sawman->focused_window_switched) { + SaWManWindow *to = sawman->focused_window_to; + + if (to) { + CoreWindow *window; + + window = to->window; + D_MAGIC_ASSERT( window, CoreWindow ); + + if (window->config.cursor_flags & DWCF_INVISIBLE) { + /* Update cursor */ + sawman_window_apply_cursor_flags( sawman, to ); + } + + if (window->cursor.surface) { + D_DEBUG_AT( SaWMan_Focus, " -> switching to window's cursor shape\n" ); + + dfb_windowstack_cursor_set_shape( window->stack, window->cursor.surface, window->cursor.hot_x, window->cursor.hot_y ); + } + + if (!(window->config.cursor_flags & DWCF_INVISIBLE)) { + /* Update cursor */ + sawman_window_apply_cursor_flags( sawman, to ); + } + } + else { + SaWManTier *tier = (SaWManTier*) sawman->tiers; + + D_MAGIC_ASSERT( tier, SaWManTier ); + + if (tier->stack->cursor.opacity) { + D_DEBUG_AT( SaWMan_Focus, " -> hiding cursor...\n" ); + + tier->stack->cursor.opacity = 0; + + dfb_wm_update_cursor( tier->stack, CCUF_OPACITY ); + } + else + D_DEBUG_AT( SaWMan_Focus, " -> cursor already hidden\n" ); + } + + sawman->focused_window_switched = false; + } + + direct_list_foreach (tier, sawman->tiers) { + int n, d; + int total; + int bounding; + bool none = false; + bool border_only; + SaWManWindow *single; + CoreLayer *layer; + CoreLayerShared *shared; + int screen_width; + int screen_height; + DFBColorKey single_key; + + idx++; + + layer = dfb_layer_at( tier->layer_id ); + D_ASSERT( layer != NULL ); + + shared = layer->shared; + D_ASSERT( shared != NULL ); + + D_MAGIC_ASSERT( tier, SaWManTier ); + + if (!tier->updates.num_regions) + continue; + + if (tier->update_once) { + if (windows_updating( sawman, tier )) + continue; + + tier->update_once = false; + } + + D_DEBUG_AT( SaWMan_Update, " -> %d updates (tier %d, layer %d)\n", + tier->updates.num_regions, idx, tier->layer_id ); + + D_ASSERT( tier->region != NULL ); + + D_DEBUG_AT( SaWMan_Update, " -> [%d] %d updates, bounding %dx%d\n", + tier->layer_id, tier->updates.num_regions, + tier->updates.bounding.x2 - tier->updates.bounding.x1 + 1, + tier->updates.bounding.y2 - tier->updates.bounding.y1 + 1 ); + + if (!tier->config.width || !tier->config.height) + continue; + + dfb_screen_get_screen_size( layer->screen, &screen_width, &screen_height ); + + single = get_single_window( sawman, tier, &none ); + + if (none && !sawman_config->show_empty) { + if (tier->active) { + D_DEBUG_AT( SaWMan_Auto, " -> Disabling region...\n" ); + + tier->active = false; + tier->single_window = NULL; /* enforce configuration to reallocate buffers */ + + dfb_layer_region_disable( tier->region ); + + if (sawman->cursor.context && tier->context->layer_id == sawman->cursor.context->layer_id) { + dfb_layer_activate_context( dfb_layer_at(sawman->cursor.context->layer_id), sawman->cursor.context ); + + dfb_layer_region_flip_update( sawman->cursor.region, NULL, DSFLIP_NONE ); + } + } + dfb_updates_reset( &tier->updates ); + continue; + } + + border_only = get_border_only( sawman, tier ); + + /* Remember color key before single mode is activated. */ + if (!tier->single_mode) + tier->key = tier->context->primary.config.src_key; + + + /* If the first mode after turning off the layer is not single, then we need + this to force a reconfiguration to reallocate the buffers. */ + if (!tier->active) { + tier->single_mode = true; /* avoid endless loop */ + tier->border_only = !border_only; /* enforce configuration to reallocate buffers */ + } + + if (single && !border_only) { + CoreWindow *window; + CoreSurface *surface; + DFBDisplayLayerOptions options = DLOP_NONE; + DFBRectangle dst = single->dst; + DFBRectangle src = single->src; + DFBRegion clip = DFB_REGION_INIT_FROM_DIMENSION( &tier->size ); + + if (shared->description.caps & DLCAPS_SCREEN_LOCATION) { + dst.x = dst.x * screen_width / tier->size.w; + dst.y = dst.y * screen_height / tier->size.h; + dst.w = dst.w * screen_width / tier->size.w; + dst.h = dst.h * screen_height / tier->size.h; + } + else { + if (dst.w != src.w || dst.h != src.h) + goto no_single; + + if (shared->description.caps & DLCAPS_SCREEN_POSITION) { + dfb_rectangle_intersect_by_region( &dst, &clip ); + + src.x += dst.x - single->dst.x; + src.y += dst.y - single->dst.y; + src.w = dst.w; + src.h = dst.h; + + dst.x += (screen_width - tier->size.w) / 2; + dst.y += (screen_height - tier->size.h) / 2; + } + } + +#ifdef SAWMAN_NO_LAYER_DOWNSCALE + if (rect.w < src.w) + goto no_single; +#endif + +#ifdef SAWMAN_NO_LAYER_DST_WINDOW + if (dst.x != 0 || dst.y != 0 || dst.w != screen_width || dst.h != screen_height) + goto no_single; +#endif + + + window = single->window; + D_MAGIC_COREWINDOW_ASSERT( window ); + + surface = window->surface; + D_ASSERT( surface != NULL ); + + if (window->config.options & DWOP_ALPHACHANNEL) + options |= DLOP_ALPHACHANNEL; + + if (window->config.options & DWOP_COLORKEYING) + options |= DLOP_SRC_COLORKEY; + + single_key = tier->single_key; + + if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) { + CorePalette *palette = surface->palette; + + D_ASSERT( palette != NULL ); + D_ASSERT( palette->num_entries > 0 ); + + dfb_surface_set_palette( tier->region->surface, surface->palette ); + + if (options & DLOP_SRC_COLORKEY) { + int index = window->config.color_key % palette->num_entries; + + single_key.r = palette->entries[index].r; + single_key.g = palette->entries[index].g; + single_key.b = palette->entries[index].b; + single_key.index = index; + } + } + else { + DFBColor color; + + dfb_pixel_to_color( surface->config.format, window->config.color_key, &color ); + + single_key.r = color.r; + single_key.g = color.g; + single_key.b = color.b; + single_key.index = window->config.color_key; + } + + /* Complete reconfig? */ + if (tier->single_window != single || + !DFB_RECTANGLE_EQUAL( tier->single_src, src ) || + tier->single_format != surface->config.format || + tier->single_options != options) + { + DFBDisplayLayerConfig config; + + D_DEBUG_AT( SaWMan_Auto, " -> Switching to %dx%d [%dx%d] %s single mode for %p on %p...\n", + single->src.w, single->src.h, src.w, src.h, + dfb_pixelformat_name( surface->config.format ), single, tier ); + + config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_OPTIONS | DLCONF_BUFFERMODE; + config.width = src.w; + config.height = src.h; + config.pixelformat = surface->config.format; + config.options = options; + config.buffermode = DLBM_FRONTONLY; + + sawman->callback.layer_reconfig.layer_id = tier->layer_id; + sawman->callback.layer_reconfig.single = (SaWManWindowHandle) single; + sawman->callback.layer_reconfig.config = config; + + switch (sawman_call( sawman, SWMCID_LAYER_RECONFIG, &sawman->callback.layer_reconfig )) { + case DFB_OK: + config = sawman->callback.layer_reconfig.config; + case DFB_NOIMPL: + /* continue, no change demanded */ + break; + + default: + goto no_single; + } + + if (dfb_layer_context_test_configuration( tier->context, &config, NULL ) != DFB_OK) + goto no_single; + + tier->single_mode = true; + tier->single_window = single; + tier->single_width = src.w; + tier->single_height = src.h; + tier->single_src = src; + tier->single_dst = dst; + tier->single_format = surface->config.format; + tier->single_options = options; + tier->single_key = single_key; + + tier->active = false; + tier->region->state |= CLRSF_FROZEN; + + dfb_updates_reset( &tier->updates ); + + dfb_layer_context_set_configuration( tier->context, &config ); + + if (shared->description.caps & DLCAPS_SCREEN_LOCATION) + dfb_layer_context_set_screenrectangle( tier->context, &dst ); + else if (shared->description.caps & DLCAPS_SCREEN_POSITION) + dfb_layer_context_set_screenposition( tier->context, dst.x, dst.y ); + + dfb_layer_context_set_src_colorkey( tier->context, + tier->single_key.r, tier->single_key.g, + tier->single_key.b, tier->single_key.index ); + + dfb_gfx_copy_to( surface, tier->region->surface, &src, 0, 0, false ); + + tier->active = true; + + if (sawman->cursor.context && tier->context->layer_id == sawman->cursor.context->layer_id) + dfb_layer_activate_context( dfb_layer_at(tier->context->layer_id), tier->context ); + + dfb_layer_region_flip_update( tier->region, NULL, flags ); + + dfb_updates_reset( &tier->updates ); + + if (1) { + SaWManTierUpdate update; + + update.regions[0].x1 = 0; + update.regions[0].y1 = 0; + update.regions[0].x2 = tier->single_width - 1; + update.regions[0].y2 = tier->single_height - 1; + + update.num_regions = 1; + + fusion_reactor_dispatch_channel( tier->reactor, SAWMAN_TIER_UPDATE, &update, sizeof(update), true, NULL ); + } + continue; + } + + /* Update destination window */ + if (!DFB_RECTANGLE_EQUAL( tier->single_dst, dst )) { + tier->single_dst = dst; + + D_DEBUG_AT( SaWMan_Auto, " -> Changing single destination to %d,%d-%dx%d.\n", + DFB_RECTANGLE_VALS(&dst) ); + + dfb_layer_context_set_screenrectangle( tier->context, &dst ); + } + else + dfb_gfx_copy_to( surface, tier->region->surface, &src, 0, 0, false ); + + /* Update color key */ + if (!DFB_COLORKEY_EQUAL( single_key, tier->single_key )) { + D_DEBUG_AT( SaWMan_Auto, " -> Changing single color key.\n" ); + + tier->single_key = single_key; + + dfb_layer_context_set_src_colorkey( tier->context, + tier->single_key.r, tier->single_key.g, + tier->single_key.b, tier->single_key.index ); + } + + tier->active = true; + + dfb_layer_region_flip_update( tier->region, NULL, flags ); + + dfb_updates_reset( &tier->updates ); + + fusion_skirmish_notify( &sawman->lock ); + continue; + } + +no_single: + + if (tier->single_mode) { + D_DEBUG_AT( SaWMan_Auto, " -> Switching back from single mode...\n" ); + + tier->border_only = !border_only; /* enforce switch */ + } + + /* Switch border/default config? */ + if (tier->border_only != border_only) { + DFBDisplayLayerConfig *config; + + tier->border_only = border_only; + + if (border_only) + config = &tier->border_config; + else + config = &tier->config; + + D_DEBUG_AT( SaWMan_Auto, " -> Switching to %dx%d %s %s mode.\n", config->width, config->height, + dfb_pixelformat_name( config->pixelformat ), border_only ? "border" : "standard" ); + + sawman->callback.layer_reconfig.layer_id = tier->layer_id; + sawman->callback.layer_reconfig.single = SAWMAN_WINDOW_NONE; + sawman->callback.layer_reconfig.config = *config; + ret = sawman_call( sawman, SWMCID_LAYER_RECONFIG, &sawman->callback.layer_reconfig ); + + /* on DFB_OK we try to overrule the default configuration */ + if ( !ret && !dfb_layer_context_test_configuration( tier->context, &(sawman->callback.layer_reconfig.config), NULL ) ) { + *config = sawman->callback.layer_reconfig.config; + D_DEBUG_AT( SaWMan_Auto, " -> Overruled to %dx%d %s %s mode.\n", config->width, config->height, + dfb_pixelformat_name( config->pixelformat ), border_only ? "border" : "standard" ); + } + + tier->active = false; + tier->region->state |= CLRSF_FROZEN; + + dfb_updates_reset( &tier->updates ); + + /* Temporarily to avoid configuration errors. */ + dfb_layer_context_set_screenposition( tier->context, 0, 0 ); + + ret = dfb_layer_context_set_configuration( tier->context, config ); + if (ret) { + D_DERROR( ret, "SaWMan/Auto: Switching to standard mode failed!\n" ); + /* fixme */ + } + + tier->size.w = config->width; + tier->size.h = config->height; + + /* Notify application manager about new tier size if previous mode was single. */ + if (tier->single_mode) + sawman_call( sawman, SWMCID_STACK_RESIZED, &tier->size ); + + if (shared->description.caps & DLCAPS_SCREEN_LOCATION) { + DFBRectangle full = { 0, 0, screen_width, screen_height }; + + dfb_layer_context_set_screenrectangle( tier->context, &full ); + } + else if (shared->description.caps & DLCAPS_SCREEN_POSITION) { + dfb_layer_context_set_screenposition( tier->context, + (screen_width - config->width) / 2, + (screen_height - config->height) / 2 ); + } + + if (config->options & DLOP_SRC_COLORKEY) { + if (DFB_PIXELFORMAT_IS_INDEXED( config->pixelformat )) { + int index; + CoreSurface *surface; + CorePalette *palette; + + surface = tier->region->surface; + D_MAGIC_ASSERT( surface, CoreSurface ); + + palette = surface->palette; + D_ASSERT( palette != NULL ); + D_ASSERT( palette->num_entries > 0 ); + + index = tier->key.index % palette->num_entries; + + dfb_layer_context_set_src_colorkey( tier->context, + palette->entries[index].r, + palette->entries[index].g, + palette->entries[index].b, + index ); + } + else + dfb_layer_context_set_src_colorkey( tier->context, + tier->key.r, tier->key.g, tier->key.b, tier->key.index ); + } + } + + if (!tier->active) { + D_DEBUG_AT( SaWMan_Auto, " -> Activating tier...\n" ); + + tier->active = true; + + DFBRegion region = { 0, 0, tier->size.w - 1, tier->size.h - 1 }; + dfb_updates_add( &tier->updates, ®ion ); + + if (sawman->cursor.context && tier->context->layer_id == sawman->cursor.context->layer_id) + dfb_layer_activate_context( dfb_layer_at(tier->context->layer_id), tier->context ); + } + + tier->single_mode = false; + tier->single_window = NULL; + + if (!tier->updates.num_regions) + continue; + + + dfb_updates_stat( &tier->updates, &total, &bounding ); + + n = tier->updates.max_regions - tier->updates.num_regions + 1; + d = n + 1; + + /* Try to optimize updates. In buffer swapping modes we can save the copy by updating everything. */ + if ((total > tier->size.w * tier->size.h) || + (total > tier->size.w * tier->size.h * 3 / 5 && (tier->context->config.buffermode == DLBM_BACKVIDEO || + tier->context->config.buffermode == DLBM_TRIPLE))) + { + DFBRegion region = { 0, 0, tier->size.w - 1, tier->size.h - 1 }; + + repaint_tier( sawman, tier, ®ion, 1, flags ); + } + else if (tier->updates.num_regions < 2 || total < bounding * n / d) + repaint_tier( sawman, tier, tier->updates.regions, tier->updates.num_regions, flags ); + else + repaint_tier( sawman, tier, &tier->updates.bounding, 1, flags ); + + dfb_updates_reset( &tier->updates ); + + fusion_skirmish_notify( &sawman->lock ); + } + + return DFB_OK; +} + +#endif // !DIRECTFB_PURE_VOODOO \ No newline at end of file diff --git a/Source/SaWMan/src/sawman_config.c b/Source/SaWMan/src/sawman_config.c new file mode 100755 index 0000000..0c50a92 --- /dev/null +++ b/Source/SaWMan/src/sawman_config.c @@ -0,0 +1,512 @@ +/* + (c) Copyright 2006-2007 directfb.org + + All rights reserved. + + Written by Denis Oliver Kropp . + + 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 + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "sawman_config.h" + + +SaWManConfig *sawman_config = NULL; + +static const char *config_usage = + "SaWMan Configuration\n" + "\n" + " --sawman-help Output SaWMan usage information and exit\n" + " --sawman: