e 0.17 ...... :)
authorCarsten Haitzler <raster@rasterman.com>
Fri, 8 Dec 2000 22:54:42 +0000 (22:54 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Fri, 8 Dec 2000 22:54:42 +0000 (22:54 +0000)
SVN revision: 3961

23 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
config.h.in [new file with mode: 0644]
configure.in [new file with mode: 0644]
e.spec [new file with mode: 0644]
po/ChangeLog [new file with mode: 0644]
po/POTFILES.in [new file with mode: 0644]
po/e.pot [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/actions.c [new file with mode: 0644]
src/border.c [new file with mode: 0644]
src/desktops.c [new file with mode: 0644]
src/e.h [new file with mode: 0644]
src/icccm.c [new file with mode: 0644]
src/main.c [new file with mode: 0644]
src/resist.c [new file with mode: 0644]
src/util.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..186ceed
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+The Rasterman <raster@rasterman.com>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..dee3047
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,20 @@
+Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+  
+The above copyright notice and this permission notice shall be included in
+all copies of the Software, its documentation and marketing & publicity 
+materials, and acknowledgment shall be given in the documentation, materials
+and software packages that this Software was used.
+   
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..e507f3c
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,14 @@
+COMPILING and INSTALLING:
+
+If you got a official release tar archive do:
+    ./configure
+    
+( otherwise if you got this from enlightenment cvs do: ./autogen.sh )
+    
+Then to compile:
+    make
+
+To install (run this as root, or the user who handles installs):
+    make install
+
+NOTE: You MUST make install Etcher for it to run properly.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..c6b6c2a
--- /dev/null
@@ -0,0 +1,31 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = intl po src
+
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
+                       config.h.in config.sub configure install-sh \
+                      ltconfig ltmain.sh missing mkinstalldirs \
+                      stamp-h.in
+
+install-data-local:
+       @$(NORMAL_INSTALL)
+       if test -d $(srcdir)/data; then \
+         $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/data; \
+         for d in $(srcdir)/data/*; do \
+           if test -f $$d; then \
+             $(INSTALL_DATA) $$d $(DESTDIR)$(pkgdatadir)/data; \
+           fi \
+         done \
+       fi
+
+dist-hook:
+       if test -d data; then \
+         mkdir $(distdir)/data; \
+         for d in data/*; do \
+           if test -f $$d; then \
+             cp -p $$d $(distdir)/d; \
+           fi \
+         done \
+       fi
+
+EXTRA_DIST = README AUTHORS COPYING e.spec
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..32dbee6
--- /dev/null
+++ b/README
@@ -0,0 +1,3 @@
+-------------------------------------------------------------------------------
+ Enlightenment 0.17.0 PRE-RELEASE.... 
+-------------------------------------------------------------------------------
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..293b797
--- /dev/null
@@ -0,0 +1,148 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+PKG_NAME="the package."
+
+DIE=0
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+  echo
+  echo "**Error**: You must have \`autoconf' installed to."
+  echo "Download the appropriate package for your distribution,"
+  echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+  DIE=1
+}
+
+(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
+  (libtool --version) < /dev/null > /dev/null 2>&1 || {
+    echo
+    echo "**Error**: You must have \`libtool' installed."
+    echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz"
+    echo "(or a newer version if it is available)"
+    DIE=1
+  }
+}
+
+grep "^AM_GNU_GETTEXT" $srcdir/configure.in >/dev/null && {
+  grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
+  (gettext --version) < /dev/null > /dev/null 2>&1 || {
+    echo
+    echo "**Error**: You must have \`gettext' installed."
+    echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
+    echo "(or a newer version if it is available)"
+    DIE=1
+  }
+}
+
+grep "^AM_GNOME_GETTEXT" $srcdir/configure.in >/dev/null && {
+  grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
+  (gettext --version) < /dev/null > /dev/null 2>&1 || {
+    echo
+    echo "**Error**: You must have \`gettext' installed."
+    echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
+    echo "(or a newer version if it is available)"
+    DIE=1
+  }
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+  echo
+  echo "**Error**: You must have \`automake' installed."
+  echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
+  echo "(or a newer version if it is available)"
+  DIE=1
+  NO_AUTOMAKE=yes
+}
+
+
+# if no automake, don't bother testing for aclocal
+test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
+  echo
+  echo "**Error**: Missing \`aclocal'.  The version of \`automake'"
+  echo "installed doesn't appear recent enough."
+  echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
+  echo "(or a newer version if it is available)"
+  DIE=1
+}
+
+if test "$DIE" -eq 1; then
+  exit 1
+fi
+
+if test -z "$*"; then
+  echo "**Warning**: I am going to run \`configure' with no arguments."
+  echo "If you wish to pass any to it, please specify them on the"
+  echo \`$0\'" command line."
+  echo
+fi
+
+case $CC in
+xlc )
+  am_opt=--include-deps;;
+esac
+
+for coin in `find $srcdir -name configure.in -print`
+do 
+  dr=`dirname $coin`
+  if test -f $dr/NO-AUTO-GEN; then
+    echo skipping $dr -- flagged as no auto-gen
+  else
+    echo processing $dr
+    macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
+    ( cd $dr
+      aclocalinclude="$ACLOCAL_FLAGS"
+      for k in $macrodirs; do
+       if test -d $k; then
+          aclocalinclude="$aclocalinclude -I $k"
+       ##else 
+       ##  echo "**Warning**: No such directory \`$k'.  Ignored."
+        fi
+      done
+      if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then
+       if grep "sed.*POTFILES" configure.in >/dev/null; then
+         : do nothing -- we still have an old unmodified configure.in
+       else
+         echo "Creating $dr/aclocal.m4 ..."
+         test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
+         echo "Running gettextize...  Ignore non-fatal messages."
+         echo "no" | gettextize --force --copy
+         echo "Making $dr/aclocal.m4 writable ..."
+         test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
+        fi
+      fi
+      if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then
+       echo "Creating $dr/aclocal.m4 ..."
+       test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
+       echo "Running gettextize...  Ignore non-fatal messages."
+       echo "no" | gettextize --force --copy
+       echo "Making $dr/aclocal.m4 writable ..."
+       test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
+      fi
+      if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
+       echo "Running libtoolize..."
+       libtoolize --force --copy
+      fi
+      echo "Running aclocal $aclocalinclude ..."
+      aclocal $aclocalinclude
+      if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
+       echo "Running autoheader..."
+       autoheader
+      fi
+      echo "Running automake --gnu $am_opt ..."
+      automake --add-missing --gnu $am_opt
+      echo "Running autoconf ..."
+      autoconf
+    )
+  fi
+done
+
+#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
+
+if test x$NOCONFIGURE = x; then
+  echo Running $srcdir/configure $conf_flags "$@" ...
+  $srcdir/configure $conf_flags "$@" \
+  && echo Now type \`make\' to compile $PKG_NAME
+else
+  echo Skipping configure process.
+fi
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..3f449a9
--- /dev/null
@@ -0,0 +1,133 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call.  */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+#undef ENABLE_NLS
+#undef HAVE_CATGETS
+#undef HAVE_GETTEXT
+#undef HAVE_LC_MESSAGES
+#undef HAVE_STPCPY
+#undef HAVE_LIBSM
+#undef PACKAGE_LOCALE_DIR
+#undef PACKAGE_DATA_DIR
+#undef PACKAGE_SOURCE_DIR
+
+/* Define if you have the __argz_count function.  */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function.  */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function.  */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function.  */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function.  */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function.  */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function.  */
+#undef HAVE_PUTENV
+
+/* Define if you have the setenv function.  */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function.  */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function.  */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function.  */
+#undef HAVE_STRCHR
+
+/* Define if you have the strdup function.  */
+#undef HAVE_STRDUP
+
+/* Define if you have the <argz.h> header file.  */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file.  */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file.  */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <nl_types.h> header file.  */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <string.h> header file.  */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/param.h> header file.  */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the i library (-li).  */
+#undef HAVE_LIBI
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if using the dmalloc debugging malloc package */
+#undef WITH_DMALLOC
+
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..b6a7ac1
--- /dev/null
@@ -0,0 +1,74 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(configure.in)
+AM_INIT_AUTOMAKE(enlightenment, 0.17.0)
+AM_CONFIG_HEADER(config.h)
+
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+
+AM_WITH_DMALLOC
+
+dnl Add the languages which your application supports here.
+ALL_LINGUAS=""
+AM_GNU_GETTEXT
+
+dnl Set PACKAGE_LOCALE_DIR in config.h.
+if test "x${prefix}" = "xNONE"; then
+  AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${ac_default_prefix}/${DATADIRNAME}/locale")
+else
+  AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${prefix}/${DATADIRNAME}/locale")
+fi
+
+dnl Set PACKAGE_DATA_DIR in config.h.
+if test "x${datadir}" = 'x${prefix}/share'; then
+  if test "x${prefix}" = "xNONE"; then
+    AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${ac_default_prefix}/share/${PACKAGE}")
+  else
+    AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${prefix}/share/${PACKAGE}")
+  fi
+else
+  AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${datadir}/${PACKAGE}")
+fi
+
+dnl Set PACKAGE_SOURCE_DIR in config.h.
+packagesrcdir=`cd $srcdir && pwd`
+AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}")
+
+dnl Use -Wall if we have gcc.
+changequote(,)dnl
+if test "x$GCC" = "xyes"; then
+  case " $CFLAGS " in
+  *[\ \        ]-Wall[\ \      ]*) ;;
+  *) CFLAGS="$CFLAGS -Wall" ;;
+  esac
+fi
+changequote([,])dnl
+
+evas_cflags=`evas-config --cflags`
+evas_libs=`evas-config --libs`
+edb_cflags=`edb-config --cflags`
+edb_libs=`edb-config --libs`
+ebits_cflags=`ebits-config --cflags`
+ebits_libs=`ebits-config --libs`
+ecore_cflags=`ecore-config --cflags`
+ecore_libs=`ecore-config --libs`
+
+AC_SUBST(evas_cflags)
+AC_SUBST(evas_libs)
+AC_SUBST(edb_cflags)
+AC_SUBST(edb_libs)
+AC_SUBST(ebits_cflags)
+AC_SUBST(ebits_libs)
+AC_SUBST(ecore_cflags)
+AC_SUBST(ecore_libs)
+
+AC_OUTPUT([
+Makefile
+src/Makefile
+intl/Makefile
+po/Makefile.in
+])
+
diff --git a/e.spec b/e.spec
new file mode 100644 (file)
index 0000000..7b168f1
--- /dev/null
+++ b/e.spec
@@ -0,0 +1,66 @@
+# Note that this is NOT a relocatable package
+%define ver      1.0
+%define rel      1
+%define prefix   /usr/local
+
+Summary: Enlightenment DR0.17's new "bit" editor
+Name: etcher
+Version: %ver
+Release: %rel
+Copyright: BSD
+Group: X11/Libraries
+Source: ftp://ftp.enlightenment.org/pub/enlightenment/etcher-%{ver}.tar.gz
+BuildRoot: /var/tmp/etcher-root
+Packager: Term <kempler@utdallas.edu>
+URL: http://www.enlightenment.org/
+Requires: evas >= 0.0.1
+Requires: edb >= 1.0.0
+Requires: imlib2 >= 1.0.0
+
+Docdir: %{prefix}/doc
+
+%description
+Etcher is a new application devised to assist would-be theme developers in
+designin "bits", that is, window borders, icons, whatever, for
+Enlightenment. Since Enlightenment DR0.17 uses drag-and-drop instead of
+texual configuration files, this application will become instrumental for
+themeing under the new Enlightenment version.
+
+%prep
+%setup
+
+%build
+./configure --prefix=%prefix
+
+if [ "$SMP" != "" ]; then
+  (make "MAKE=make -k -j $SMP"; exit 0)
+  make
+else
+  make
+fi
+###########################################################################
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make prefix=$RPM_BUILD_ROOT%{prefix} install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+
+%postun
+
+%files
+%defattr(-,root,root)
+%doc README COPYING ChangeLog
+%attr(755,root,root) %{prefix}/bin/etcher
+%{prefix}/share/etcher/*
+
+%doc AUTHORS
+%doc COPYING
+%doc README
+
+%changelog
+* Mon Aug 28 2000 Lyle Kempler <kempler@utdallas.edu>
+- Created spec file
diff --git a/po/ChangeLog b/po/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644 (file)
index 0000000..a0b3c55
--- /dev/null
@@ -0,0 +1,3 @@
+# List of source files containing translatable strings.
+
+src/main.c
diff --git a/po/e.pot b/po/e.pot
new file mode 100644 (file)
index 0000000..a3edd95
--- /dev/null
+++ b/po/e.pot
@@ -0,0 +1,15 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2000-11-02 16:32-0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..eb7caf2
--- /dev/null
@@ -0,0 +1,20 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+       -I$(top_srcdir)/intl \
+       @evas_cflags@ @edb_cflags@ @ebits_cflags@ @ecore_cflags@
+
+bin_PROGRAMS = e
+
+e_SOURCES = \
+actions.c \
+border.c \
+desktops.c \
+icccm.c \
+main.c \
+resist.c \
+util.c \
+e.h
+
+e_LDADD = @evas_libs@ @edb_libs@ @ebits_libs@ @ecore_libs@ -lecore -lm $(INTLLIBS)
+
diff --git a/src/actions.c b/src/actions.c
new file mode 100644 (file)
index 0000000..1679c2f
--- /dev/null
@@ -0,0 +1,748 @@
+#include "e.h"
+
+static Evas_List action_protos = NULL;
+static Evas_List current_actions = NULL;
+
+static void _e_action_find(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o);
+static void _e_action_free(E_Action *a);
+
+static void e_act_move_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_move_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_move_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy);
+
+static void e_act_resize_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_resize_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_resize_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy);
+
+static void e_act_resize_h_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_resize_h_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_resize_h_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy);
+
+static void e_act_resize_v_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_resize_v_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+static void e_act_resize_v_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy);
+
+static void e_act_close_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_kill_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_shade_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_raise_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_lower_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_raise_lower_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_exec_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_menu_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_exit_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_restart_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_stick_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_sound_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_iconify_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_max_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_snap_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void e_act_zoom_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+
+static void
+_e_action_find(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o)
+{
+   char *actions_db = "./actions.db";
+   E_DB_File *db;
+   int i, num;
+   char *a_name = NULL;
+   char *a_action = NULL;
+   char *a_params = NULL;
+   int   a_event = 0;
+   int   a_button = 0;
+   char *a_key = NULL;
+   int   a_modifiers = 0;
+   E_Action *a;
+
+   db = e_db_open_read(actions_db);
+   if (!db) return;
+   if (!e_db_int_get(db, "/actions/count", &num)) goto error;
+   for (i = 0; i < num; i++)
+     {
+       char buf[4096];
+       Evas_List l;
+       a = NULL;
+       
+       a = NULL;
+       sprintf(buf, "/actions/%i/name", i);
+       a_name = e_db_str_get(db, buf);
+       sprintf(buf, "/actions/%i/action", i);
+       a_action = e_db_str_get(db, buf);
+       sprintf(buf, "/actions/%i/params", i);
+       a_params = e_db_str_get(db, buf);
+       sprintf(buf, "/actions/%i/event", i);
+       e_db_int_get(db, buf, &a_event);
+       sprintf(buf, "/actions/%i/button", i);
+       e_db_int_get(db, buf, &a_button);
+       sprintf(buf, "/actions/%i/key", i);
+       a_key = e_db_str_get(db, buf);
+       sprintf(buf, "/actions/%i/modifiers", i);
+       e_db_int_get(db, buf, &a_modifiers);
+       
+       if (act != a_event) goto next;
+       if (!((a_name) && 
+             (action) && 
+             (!strcmp(a_name, action)))) goto next;
+       if ((act >= ACT_MOUSE_CLICK) && 
+           (act <= ACT_MOUSE_CLICKED) && 
+           (!((a_button == -1) || 
+              (a_button == button)))) goto next;
+       if ((act >= ACT_KEY_DOWN) && 
+           (act <= ACT_KEY_UP) &&
+           (!((a_key) && (key) &&
+              (!strcmp(a_key, key))))) goto next;
+       if ((act >= ACT_MOUSE_CLICK) &&
+           (act <= ACT_KEY_UP) &&
+           (!((a_modifiers == -1) || 
+              (a_modifiers == (int)mods)))) goto next;
+       for (l = action_protos; l; l = l->next)
+         {
+            E_Action_Proto *ap;
+            
+            ap = l->data;
+            if (!strcmp(ap->action, a_action))
+              {
+                 
+                 a = NEW(E_Action, 1);
+                 ZERO(a, E_Action, 1);
+                 
+                 OBJ_INIT(a, _e_action_free);
+                 
+                 a->name = a_name;
+                 a->action = a_action;
+                 a->params = a_params;
+                 a->event = a_event;
+                 a->button = a_button;
+                 a->key = a_key;
+                 a->modifiers = a_modifiers;
+                 a->action_proto = ap;
+                 a->object = o;
+                 a->started = 0;
+                 current_actions = evas_list_append(current_actions, a);
+              }
+         }
+       next:
+       if (!a)
+         {
+            IF_FREE(a_name);
+            IF_FREE(a_action);
+            IF_FREE(a_params);
+            IF_FREE(a_key);
+         }
+     }
+   error:
+   e_db_close(db);
+}
+
+static void
+_e_action_free(E_Action *a)
+{
+   IF_FREE(a->name);
+   IF_FREE(a->action);
+   IF_FREE(a->params);
+   IF_FREE(a->key);
+   FREE(a);
+}
+
+void
+e_action_start(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o, void *data, int x, int y, int rx, int ry)
+{
+   Evas_List l;
+   
+   _e_action_find(action, act, button, key, mods, o);
+   again:
+   for (l = current_actions; l; l = l->next)
+     {
+       E_Action *a;
+       
+       a = l->data;
+       if (!a->started)
+         {
+            if (a->action_proto->func_stop)
+              a->started = 1;
+            if (a->action_proto->func_start)
+              {
+                 E_Object *obj;
+                 
+                 if (a->object)
+                   {
+                      obj = a->object;
+                      if (a->started)
+                        OBJ_REF(obj);
+                   }
+                 a->action_proto->func_start(a->object, a, data, x, y, rx, ry);
+              }
+         }
+       if (!a->started)
+         {
+            current_actions = evas_list_remove(current_actions, a);
+            OBJ_DO_FREE(a);
+            goto again;
+         }
+     }
+}
+
+void
+e_action_stop(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o, void *data, int x, int y, int rx, int ry)
+{
+   Evas_List l;
+
+   again:
+   for (l = current_actions; l; l = l->next)
+     {
+       E_Action *a;
+       
+       a = l->data;
+       if ((a->started) && (a->action_proto->func_stop))
+         {
+            int ok = 0;
+            
+            if ((a->event == ACT_MOUSE_IN) && 
+                (act == ACT_MOUSE_OUT))
+              ok = 1;
+            if ((a->event == ACT_MOUSE_OUT) && 
+                (act == ACT_MOUSE_IN))
+              ok = 1;
+            if ((a->event >= ACT_MOUSE_CLICK) && 
+                (a->event <= ACT_MOUSE_TRIPLE) &&
+                (act >= ACT_MOUSE_UP) &&
+                (act <= ACT_MOUSE_CLICKED) &&
+                (a->button == button))
+              ok = 1;
+            if ((a->event == ACT_MOUSE_MOVE) && 
+                ((act == ACT_MOUSE_OUT) ||
+                 (act == ACT_MOUSE_IN) ||
+                 ((act >= ACT_MOUSE_CLICK) &&
+                  (act <= ACT_MOUSE_TRIPLE)) ||
+                 (act >= ACT_MOUSE_UP)))
+              ok = 1;
+            if ((a->event == ACT_KEY_DOWN) && 
+                (act == ACT_KEY_UP) &&
+                (key) && (a->key) && (!strcmp(key, a->key)))
+              ok = 1;
+            if ((a->event == ACT_KEY_UP) && 
+                (act == ACT_KEY_DOWN))
+              ok = 1;
+            if (ok)
+              {
+                 E_Object *obj;
+                 
+                 if (a->object)
+                   {
+                      obj = a->object;
+                      OBJ_UNREF(obj);
+                   }
+                 a->action_proto->func_stop(a->object, a, data, x, y, rx, ry);
+                 a->started = 0;
+              }
+         }
+       if (!a->started)
+         {
+            current_actions = evas_list_remove(current_actions, a);
+            OBJ_DO_FREE(a);
+            goto again;
+         }
+     }
+}
+
+void
+e_action_go(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o, void *data, int x, int y, int rx, int ry, int dx, int dy)
+{
+   Evas_List l;
+
+   for (l = current_actions; l; l = l->next)
+     {
+       E_Action *a;
+       
+       a = l->data;
+       if ((a->started) && (a->action_proto->func_go))
+         a->action_proto->func_go(a->object, a, data, x, y, rx, ry, dx, dy);
+     }
+}
+
+void
+e_action_stop_by_object(void *o, void *data, int x, int y, int rx, int ry)
+{
+   Evas_List l;
+
+   again:
+   for (l = current_actions; l; l = l->next)
+     {
+       E_Action *a;
+       
+       a = l->data;
+       if ((a->started) && (o == a->object))
+         {
+            E_Object *obj;
+            
+            if (a->object)
+              {
+                 obj = a->object;
+                 OBJ_UNREF(obj);
+              }
+            if (a->action_proto->func_stop)
+              a->action_proto->func_stop(a->object, a, data, x, y, rx, ry);
+            a->started = 0;
+            current_actions = evas_list_remove(current_actions, a);
+            OBJ_DO_FREE(a);
+            goto again;
+         }
+     }
+}
+
+void
+e_action_add_proto(char *action, 
+                  void (*func_start) (void *o, E_Action *a, void *data, int x, int y, int rx, int ry),
+                  void (*func_stop)  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry),
+                  void (*func_go)    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy))
+{
+   E_Action_Proto *ap;
+   
+   ap = NEW(E_Action_Proto, 1);
+   
+   OBJ_INIT(ap, NULL);
+   
+   ap->action = strdup(action);
+   ap->func_start = func_start;
+   ap->func_stop = func_stop;
+   ap->func_go = func_go;
+   action_protos = evas_list_append(action_protos, ap);
+}
+
+void
+e_actions_init(void)
+{
+   e_action_add_proto("Window_Move", e_act_move_start, e_act_move_stop, e_act_move_go);
+   e_action_add_proto("Window_Resize", e_act_resize_start, e_act_resize_stop, e_act_resize_go);
+   e_action_add_proto("Window_Resize_Horizontal", e_act_resize_h_start, e_act_resize_h_stop, e_act_resize_h_go);
+   e_action_add_proto("Window_Resize_Vertical", e_act_resize_v_start, e_act_resize_v_stop, e_act_resize_v_go);
+   e_action_add_proto("Window_Close", e_act_close_start, NULL, NULL);
+   e_action_add_proto("Window_Kill", e_act_kill_start, NULL, NULL);
+   e_action_add_proto("Window_Shade", e_act_shade_start, NULL, NULL);
+   e_action_add_proto("Window_Raise", e_act_raise_start, NULL, NULL);
+   e_action_add_proto("Window_Lower", e_act_lower_start, NULL, NULL);
+   e_action_add_proto("Window_Raise_Lower", e_act_raise_lower_start, NULL, NULL);
+   e_action_add_proto("Execute", e_act_exec_start, NULL, NULL);
+   e_action_add_proto("Menu", e_act_menu_start, NULL, NULL);
+   e_action_add_proto("Exit", e_act_exit_start, NULL, NULL);
+   e_action_add_proto("Restart", e_act_restart_start, NULL, NULL);
+   e_action_add_proto("Window_Stick", e_act_stick_start, NULL, NULL);
+   e_action_add_proto("Sound", e_act_sound_start, NULL, NULL);
+   e_action_add_proto("Window_Iconify", e_act_iconify_start, NULL, NULL);
+   e_action_add_proto("Window_Max_Size", e_act_max_start, NULL, NULL);
+   e_action_add_proto("Winodw_Snap", e_act_snap_start, NULL, NULL);
+   e_action_add_proto("Window_Zoom", e_act_zoom_start, NULL, NULL);
+}
+
+
+
+
+
+
+
+
+static void 
+e_act_move_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   b->mode.move = 1;
+   b->current.requested.dx = 0;
+   b->current.requested.dy = 0;
+   b->previous.requested.dx = 0;
+   b->previous.requested.dy = 0;
+}
+
+static void
+e_act_move_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   b->current.requested.x = b->current.x;
+   b->current.requested.y = b->current.y;
+   b->changed = 1;
+   b->mode.move = 0;
+   b->current.requested.dx = 0;
+   b->current.requested.dy = 0;
+   b->previous.requested.dx = 0;
+   b->previous.requested.dy = 0;
+   e_border_adjust_limits(b);
+}
+
+static void
+e_act_move_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy)
+{
+   E_Border *b;
+   
+   b = o;
+   b->current.requested.x += dx;
+   b->current.requested.y += dy;
+   if (dx != 0) b->current.requested.dx = dx;
+   if (dy != 0) b->current.requested.dy = dy;
+   b->changed = 1;
+   e_border_adjust_limits(b);
+}
+
+
+static void 
+e_act_resize_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   /* 0 | 1 */
+   /* --+-- */
+   /* 2 | 3 */
+   if (x > (b->current.w / 2)) 
+     {
+       if (y > (b->current.h / 2)) 
+         {
+            b->mode.resize = 3;
+            SET_BORDER_GRAVITY(b, NorthWestGravity);
+         }
+       else 
+         {
+            b->mode.resize = 1;
+            SET_BORDER_GRAVITY(b, SouthWestGravity);
+         }
+     }
+   else
+     {
+       if (y > (b->current.h / 2)) 
+         {
+            b->mode.resize = 2;
+            SET_BORDER_GRAVITY(b, NorthEastGravity);
+         }
+       else 
+         {
+            b->mode.resize = 0;
+            SET_BORDER_GRAVITY(b, SouthEastGravity);
+         }
+     }
+}
+
+static void
+e_act_resize_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   b->current.requested.x = b->current.x;
+   b->current.requested.y = b->current.y;
+   b->current.requested.w = b->current.w;
+   b->current.requested.h = b->current.h;
+   b->mode.resize = 0;
+   b->changed = 1;
+   e_border_adjust_limits(b);
+}
+
+static void
+e_act_resize_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy)
+{
+   E_Border *b;
+   
+   b = o;
+   if (b->mode.resize == 0)
+     {
+       b->current.requested.w -= dx;
+       b->current.requested.h -= dy;
+       b->current.requested.x += dx;
+       b->current.requested.y += dy;
+     }
+   else if (b->mode.resize == 1)
+     {
+       b->current.requested.w += dx;
+       b->current.requested.h -= dy;
+       b->current.requested.y += dy;
+     }
+   else if (b->mode.resize == 2)
+     {
+       b->current.requested.w -= dx;
+       b->current.requested.h += dy;
+       b->current.requested.x += dx;
+     }
+   else if (b->mode.resize == 3)
+     {
+       b->current.requested.w += dx;
+       b->current.requested.h += dy;
+     }
+   b->changed = 1;
+   e_border_adjust_limits(b);
+}
+
+
+static void 
+e_act_resize_h_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   /* 4 | 5 */
+   if (x > (b->current.w / 2)) 
+     {
+       b->mode.resize = 5;
+       SET_BORDER_GRAVITY(b, NorthWestGravity);
+     }
+   else 
+     {
+       b->mode.resize = 4;
+       SET_BORDER_GRAVITY(b, NorthEastGravity);
+     }
+}
+
+static void
+e_act_resize_h_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   b->current.requested.x = b->current.x;
+   b->current.requested.y = b->current.y;
+   b->current.requested.w = b->current.w;
+   b->current.requested.h = b->current.h;
+   b->mode.resize = 0;
+   b->changed = 1;
+   e_border_adjust_limits(b);
+}
+
+static void
+e_act_resize_h_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy)
+{
+   E_Border *b;
+   
+   b = o;
+   if (b->mode.resize == 4)
+     {
+       b->current.requested.w -= dx;
+       b->current.requested.x += dx;
+     }
+   else if (b->mode.resize == 5)
+     {
+       b->current.requested.w += dx;
+     }
+   b->changed = 1;
+   e_border_adjust_limits(b);
+}
+
+
+static void 
+e_act_resize_v_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   /* 6 */
+   /* - */
+   /* 7 */
+   if (y > (b->current.h / 2)) 
+     {
+       b->mode.resize = 7;
+       SET_BORDER_GRAVITY(b, NorthWestGravity);
+     }
+   else 
+     {
+       b->mode.resize = 6;
+       SET_BORDER_GRAVITY(b, SouthWestGravity);
+     }
+}
+
+static void
+e_act_resize_v_stop  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   b->current.requested.x = b->current.x;
+   b->current.requested.y = b->current.y;
+   b->current.requested.w = b->current.w;
+   b->current.requested.h = b->current.h;
+   b->mode.resize = 0;
+   e_border_adjust_limits(b);
+   b->changed = 1;
+}
+
+static void
+e_act_resize_v_go    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy)
+{
+   E_Border *b;
+   
+   b = o;
+   if (b->mode.resize == 6)
+     {
+       b->current.requested.h -= dy;
+       b->current.requested.y += dy;
+     }
+   else if (b->mode.resize == 7)
+     {
+       b->current.requested.h += dy;
+     }
+   e_border_adjust_limits(b);
+   b->changed = 1;
+}
+
+
+static void 
+e_act_close_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   if (b->win.client) e_icccm_delete(b->win.client);
+}
+
+
+static void 
+e_act_kill_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   if (b->win.client) e_window_kill_client(b->win.client);
+}
+
+
+static void 
+e_act_shade_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_raise_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   e_border_raise(b);
+}
+
+
+static void 
+e_act_lower_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   e_border_lower(b);
+}
+
+
+static void 
+e_act_raise_lower_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_exec_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_menu_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_exit_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+   exit(0);
+}
+
+
+static void 
+e_act_restart_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_stick_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_sound_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_iconify_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_max_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_snap_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
+
+static void 
+e_act_zoom_start (void *o, E_Action *a, void *data, int x, int y, int rx, int ry)
+{
+   E_Border *b;
+   
+   b = o;
+}
+
diff --git a/src/border.c b/src/border.c
new file mode 100644 (file)
index 0000000..dcb645e
--- /dev/null
@@ -0,0 +1,1803 @@
+#include "e.h"
+
+/* Window border rendering, querying, setting  & modification code */
+
+/* globals local to window borders */
+static Evas_List evases = NULL;
+static Evas_List borders = NULL;
+
+static int mouse_x, mouse_y, mouse_win_x, mouse_win_y;
+static int mouse_buttons = 0;
+
+static int border_mouse_x = 0;
+static int border_mouse_y = 0;
+static int border_mouse_buttons = 0;
+
+static Eevent *current_ev = NULL;
+
+static void e_idle(void *data);
+static void e_map_request(Eevent * ev);
+static void e_configure_request(Eevent * ev);
+static void e_property(Eevent * ev);
+static void e_unmap(Eevent * ev);
+static void e_destroy(Eevent * ev);
+static void e_circulate_request(Eevent * ev);
+static void e_reparent(Eevent * ev);
+static void e_shape(Eevent * ev);
+static void e_focus_in(Eevent * ev);
+static void e_focus_out(Eevent * ev);
+static void e_colormap(Eevent * ev);
+static void e_mouse_down(Eevent * ev);
+static void e_mouse_up(Eevent * ev);
+static void e_mouse_in(Eevent * ev);
+static void e_mouse_out(Eevent * ev);
+static void e_window_expose(Eevent * ev);
+
+static void e_cb_mouse_in(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
+static void e_cb_mouse_out(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
+static void e_cb_mouse_down(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
+static void e_cb_mouse_up(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
+static void e_cb_mouse_move(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
+
+static void e_cb_border_mouse_in(E_Border *b, Eevent *e);
+static void e_cb_border_mouse_out(E_Border *b, Eevent *e);
+static void e_cb_border_mouse_down(E_Border *b, Eevent *e);
+static void e_cb_border_mouse_up(E_Border *b, Eevent *e);
+static void e_cb_border_mouse_move(E_Border *b, Eevent *e);
+static void e_cb_border_move_resize(E_Border *b);
+static void e_cb_border_visibility(E_Border *b);
+
+static void e_border_poll(int val, void *data);
+
+/* what to dowhen we're idle */
+static void
+e_idle(void *data)
+{
+   Evas_List l;
+
+   for (l = borders; l; l = l->next)
+     {
+       E_Border *b;
+       
+       b = l->data;
+       e_border_update(b);
+     }
+   for (l = evases; l; l = l->next)
+     {
+       Evas evas;
+       
+       evas = l->data;
+       evas_render(evas);
+     }
+   e_db_runtime_flush();
+}
+
+/* */
+static void
+e_map_request(Eevent * ev)
+{
+   Ev_Window_Map_Request      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       E_Border *b;
+       
+       printf("map request %x\n", e->win);
+       b = e_border_find_by_window(e->win);
+       if (!b)
+         {
+            b = e_border_adopt(e->win, 0);
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_configure_request(Eevent * ev)
+{
+   Ev_Window_Configure_Request      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            int pl, pr, pt, pb;
+      
+            pl = pr = pt = pb = 0;
+            if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
+            if (e->mask & EV_VALUE_X)
+              {
+                 printf("request move to %i %i\n", e->x, e->y);
+              }
+            if (e->mask & EV_VALUE_X)
+               b->current.requested.x = e->x;
+            if (e->mask & EV_VALUE_Y)
+               b->current.requested.y = e->y;
+            if (e->mask & EV_VALUE_W)
+               b->current.requested.w = e->w + pl + pr;
+            if (e->mask & EV_VALUE_H)
+               b->current.requested.h = e->h + pt + pb;
+            if ((e->mask & EV_VALUE_SIBLING) && (e->mask & EV_VALUE_STACKING))
+              {
+                 E_Border *b_rel;
+                 
+                 b_rel = e_border_find_by_window(e->stack_win);
+                 if (b_rel)
+                   {
+                      if (e->detail == EV_STACK_ABOVE) e_border_raise_above(b, b_rel);
+                      else if (e->detail == EV_STACK_BELOW) e_border_lower_below(b, b_rel);
+                      /* FIXME: need to handle  & fix
+                       * EV_STACK_TOP_IF 
+                       * EV_STACK_BOTTOM_IF 
+                       * EV_STACK_OPPOSITE 
+                       */
+                      else if (e->detail == EV_STACK_TOP_IF) e_border_raise(b);
+                      else if (e->detail == EV_STACK_BOTTOM_IF) e_border_lower(b);
+                   }
+              }
+            else if (e->mask & EV_VALUE_STACKING)
+              {
+                 if (e->detail == EV_STACK_ABOVE) e_border_raise(b);
+                 else if (e->detail == EV_STACK_BELOW) e_border_lower(b);
+                      /* FIXME: need to handle  & fix
+                       * EV_STACK_TOP_IF 
+                       * EV_STACK_BOTTOM_IF 
+                       * EV_STACK_OPPOSITE 
+                       */
+                 else if (e->detail == EV_STACK_TOP_IF) e_border_raise(b);
+                 else if (e->detail == EV_STACK_BOTTOM_IF) e_border_lower(b);
+              }
+            b->changed = 1;
+            e_border_adjust_limits(b);
+         }
+       else
+         {
+            if ((e->mask & EV_VALUE_X) && (e->mask & EV_VALUE_W))
+               e_window_move_resize(e->win, e->x, e->y, e->w, e->h);
+            else if ((e->mask & EV_VALUE_W))
+               e_window_resize(e->win, e->w, e->h);
+            else if ((e->mask & EV_VALUE_X))
+               e_window_move(e->win, e->x, e->y);
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_property(Eevent * ev)
+{
+   Ev_Window_Property      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_unmap(Eevent * ev)
+{
+   Ev_Window_Unmap      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            if (b->win.client == e->win)
+              {
+                 if (b->ignore_unmap > 0) b->ignore_unmap--;
+                 else
+                   {
+                      printf("unmap %x\n", e->win);
+                      e_action_stop_by_object(b, NULL, 
+                                              mouse_win_x, mouse_win_y, 
+                                              border_mouse_x, border_mouse_y);
+                      OBJ_UNREF(b);
+                      OBJ_IF_FREE(b)
+                        {
+                           e_window_reparent(e->win, 0, 0, 0);
+                           e_icccm_release(e->win);
+                           OBJ_FREE(b);
+                        }
+                   }
+              }
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_destroy(Eevent * ev)
+{
+   Ev_Window_Destroy      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            printf("destroy %x\n", e->win);
+            if (b->win.client == e->win)
+              {
+                 e_action_stop_by_object(b, NULL, 
+                                         mouse_win_x, mouse_win_y, 
+                                         border_mouse_x, border_mouse_y);
+                 OBJ_UNREF(b);
+                 OBJ_IF_FREE(b)
+                   {
+                      e_window_reparent(e->win, 0, 0, 0);
+                      e_icccm_release(e->win);
+                      OBJ_FREE(b);
+                   }
+              }
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_circulate_request(Eevent * ev)
+{
+   Ev_Window_Circulate_Request      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            if (e->lower) e_border_lower(b);
+            else e_border_raise(b);
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_reparent(Eevent * ev)
+{
+   Ev_Window_Reparent      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+#if 0   
+     {
+       Evas_List l;
+       E_Border *b;
+
+       b = e_border_find_by_window(e->win);
+       if ((b) && (e->parent_from == b->win.container))
+         {
+            if (b)
+              {
+                 e_action_stop_by_object(b, NULL, 
+                                         mouse_win_x, mouse_win_y, 
+                                         border_mouse_x, border_mouse_y);
+                 OBJ_UNREF(b);
+                 OBJ_IF_FREE(b)
+                   {
+                      e_window_reparent(e->win, 0, 0, 0);
+                      e_icccm_release(e->win);
+                      OBJ_FREE(b);
+                   }
+              }
+         }
+     }
+#endif   
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_shape(Eevent * ev)
+{
+   Ev_Window_Shape      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_focus_in(Eevent * ev)
+{
+   Ev_Window_Focus_In   *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            b->current.selected = 1;
+            b->changed = 1;
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_focus_out(Eevent * ev)
+{
+   Ev_Window_Focus_Out      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {     
+            char *settings_db = "./settings.db";
+            E_DB_File *db;
+            int focus_mode;
+            char buf[4096];
+   
+            b->current.selected = 0;
+            /* settings - click to focus would affect grabs */
+            db = e_db_open_read(settings_db);   
+            sprintf(buf, "/focus/mode");
+            if ((db) && (e_db_int_get(db, buf, &focus_mode)) && (!b->current.selected))
+              {
+                 if (focus_mode == 2) /* click to focus */
+                   {
+                      E_Grab *g;
+                      
+                      g = NEW(E_Grab, 1);
+                      ZERO(g, E_Grab, 1);
+                      g->button = 0;
+                      g->mods = 0;
+                      g->any_mod = 1;
+                      g->remove_after = 1;
+                      b->grabs = evas_list_append(b->grabs, g);
+                      e_button_grab(b->win.main, 0, XEV_BUTTON | XEV_MOUSE_MOVE, EV_KEY_MODIFIER_NONE, 1);
+                      e_db_close(db);
+                   }
+              }
+            b->changed = 1;
+         }
+     }
+   current_ev = NULL;
+}
+
+/* */
+static void
+e_colormap(Eevent * ev)
+{
+   Ev_Colormap      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+         }
+     }
+   current_ev = NULL;
+}
+
+/* handling mouse down events */
+static void
+e_mouse_down(Eevent * ev)
+{
+   Ev_Mouse_Down      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       mouse_win_x = e->x;
+       mouse_win_y = e->y;
+       mouse_x = e->rx;
+       mouse_y = e->ry;
+       mouse_buttons |= (1 << e->button);
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            if (e->win == b->win.main) e_cb_border_mouse_down(b, ev);
+            else
+              {
+                 Evas evas;
+                 int x, y;
+                 
+                 evas = b->evas.l;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_down(evas, x, y, e->button);
+                 evas = b->evas.r;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_down(evas, x, y, e->button);
+                 evas = b->evas.t;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_down(evas, x, y, e->button);
+                 evas = b->evas.b;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_down(evas, x, y, e->button);
+              }
+         }
+     }
+   current_ev = NULL;
+}
+
+/* handling mouse up events */
+static void
+e_mouse_up(Eevent * ev)
+{
+   Ev_Mouse_Up      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       mouse_win_x = e->x;
+       mouse_win_y = e->y;
+       mouse_x = e->rx;
+       mouse_y = e->ry;
+       mouse_buttons &= ~(1 << e->button);
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {     
+            if (e->win == b->win.main) e_cb_border_mouse_up(b, ev);
+            else
+              {
+                 Evas evas;
+                 int x, y;
+                      
+                 evas = b->evas.l;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_up(evas, x, y, e->button);
+                 evas = b->evas.r;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_up(evas, x, y, e->button);
+                 evas = b->evas.t;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_up(evas, x, y, e->button);
+                 evas = b->evas.b;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_up(evas, x, y, e->button);
+              }
+         }
+     }
+   current_ev = NULL;
+}
+
+/* handling mouse move events */
+static void
+e_mouse_move(Eevent * ev)
+{
+   Ev_Mouse_Move      *e;
+
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       E_Border *b;
+       
+       mouse_win_x = e->x;
+       mouse_win_y = e->y;
+       mouse_x = e->rx;
+       mouse_y = e->ry;
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            if (e->win == b->win.main) e_cb_border_mouse_move(b, ev);
+            else
+              {
+                 Evas evas;
+                 int x, y;
+                 
+                 evas = b->evas.l;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas = b->evas.r;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas = b->evas.t;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas = b->evas.b;
+                 e_window_get_root_relative_location(evas_get_window(evas), 
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+              }
+         }
+     }
+   current_ev = NULL;
+}
+
+/* handling mouse enter events */
+static void
+e_mouse_in(Eevent * ev)
+{
+   Ev_Window_Enter      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            if (e->win == b->win.main) e_cb_border_mouse_in(b, ev);
+            if (e->win == b->win.input)
+              {
+                 int x, y;
+                 Evas evas;
+                 
+                 evas = b->evas.l;
+                 e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas_event_enter(evas);
+                 
+                 evas = b->evas.r;
+                 e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas_event_enter(evas);
+                 
+                 evas = b->evas.t;
+                 e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas_event_enter(evas);
+                 
+                 evas = b->evas.b;
+                 e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas_event_enter(evas);
+              }
+         }
+     }
+   current_ev = NULL;
+}
+
+/* handling mouse leave events */
+static void
+e_mouse_out(Eevent * ev)
+{
+   Ev_Window_Leave      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       E_Border *b;
+       
+       b = e_border_find_by_window(e->win);
+       if (b)
+         {
+            if (e->win == b->win.main) e_cb_border_mouse_out(b, ev);
+            if (e->win == b->win.input)
+              {
+                 evas_event_leave(b->evas.l);
+                 evas_event_leave(b->evas.r);
+                 evas_event_leave(b->evas.t);
+                 evas_event_leave(b->evas.b);
+              }
+         }
+     }
+   current_ev = NULL;
+   current_ev = NULL;
+}
+
+/* handling expose events */
+static void
+e_window_expose(Eevent * ev)
+{
+   Ev_Window_Expose      *e;
+   
+   current_ev = ev;
+   e = ev->event;
+     {
+       Evas_List l;
+       
+       for (l = evases; l; l = l->next)
+         {
+            Evas evas;
+
+            evas = l->data;
+            if (evas_get_window(evas) == e->win)
+              evas_update_rect(evas, e->x, e->y, e->w, e->h);
+         }
+     }
+   current_ev = NULL;
+}
+
+/* what to do with border events */
+
+static void
+e_cb_mouse_in(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
+{
+   E_Border *b;
+   
+   b = data;
+   if (border_mouse_buttons) return;
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   if (!current_ev) return;
+   e_action_stop(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+   e_action_start(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+}
+
+static void
+e_cb_mouse_out(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
+{
+   E_Border *b;
+   
+   b = data;
+   if (border_mouse_buttons) return;
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   if (!current_ev) return;
+   e_action_stop(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+   e_action_start(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+}
+
+static void
+e_cb_mouse_down(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
+{
+   E_Border *b;
+   
+   b = data;
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   border_mouse_buttons = mouse_buttons;
+   if (!current_ev) return;
+     {
+       int act;
+       Ev_Key_Modifiers mods;
+       
+       mods = ((Ev_Mouse_Down *)(current_ev->event))->mods;
+       act = ACT_MOUSE_CLICK;
+       if (((Ev_Mouse_Down *)(current_ev->event))->double_click) act = ACT_MOUSE_DOUBLE;
+       else if (((Ev_Mouse_Down *)(current_ev->event))->triple_click) act = ACT_MOUSE_TRIPLE;
+       e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+       e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+     }
+}
+
+static void
+e_cb_mouse_up(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
+{
+   E_Border *b;
+   
+   b = data;
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   border_mouse_buttons = mouse_buttons;
+   if (!current_ev) return;
+     {
+       int act;
+       Ev_Key_Modifiers mods;
+       
+       mods = ((Ev_Mouse_Up *)(current_ev->event))->mods;
+       act = ACT_MOUSE_UP;
+       if ((x >= ox) && (x < (ox + ow)) && (y >= oy) && (y < (oy + oh)))
+         act = ACT_MOUSE_CLICKED;
+       e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+       e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+     }
+}
+
+static void
+e_cb_mouse_move(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
+{
+   E_Border *b;
+   int dx, dy;
+   
+   b = data;
+   dx = mouse_x - border_mouse_x;
+   dy = mouse_y - border_mouse_y;
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   if (!current_ev) return;
+   e_action_go(class, ACT_MOUSE_MOVE, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y, dx, dy);
+}
+
+/* callbacks for certain things */
+static void
+e_cb_border_mouse_in(E_Border *b, Eevent *e)
+{
+   E_Action *a;
+   int x, y;
+   char *class = "Window_Grab";
+   
+   if (border_mouse_buttons) return;
+   /* pointer focus stuff */
+   e_focus_to_window(b->win.client);
+
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   border_mouse_buttons = mouse_buttons;
+   if (!current_ev) return;
+   x = ((Ev_Window_Enter *)(e->event))->x;
+   y = ((Ev_Window_Enter *)(e->event))->y;
+   e_action_stop(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+   e_action_start(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+}
+
+static void
+e_cb_border_mouse_out(E_Border *b, Eevent *e)
+{
+   E_Action *a;
+   int x, y;
+   char *class = "Window_Grab";
+
+   if (border_mouse_buttons) return;
+   /* pointer focus stuff */
+   e_focus_to_window(0);
+
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   border_mouse_buttons = mouse_buttons;
+   if (!current_ev) return;
+   e_action_stop(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+   e_action_start(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
+}
+
+static void
+e_cb_border_mouse_down(E_Border *b, Eevent *e)
+{
+   E_Action *a;
+   int x, y, bt;
+   char *class = "Window_Grab";
+   
+   e_pointer_grab(b->win.main, CurrentTime);
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   if (border_mouse_buttons) return;
+   border_mouse_buttons = mouse_buttons;
+   if (!current_ev) return;
+   x = ((Ev_Mouse_Down *)(e->event))->x;
+   y = ((Ev_Mouse_Down *)(e->event))->y;
+   bt = ((Ev_Mouse_Down *)(e->event))->button;
+     {
+       Evas_List l;
+       
+       again:
+       for (l = b->grabs; l; l = l->next)
+         {
+            E_Grab *g;
+            
+            g = l->data;
+            /* find a grab that triggered this */
+            if ((((Ev_Mouse_Down *)(e->event))->button == g->button) &&
+                ((g->any_mod) ||
+                 (((Ev_Mouse_Down *)(e->event))->mods == g->mods)))
+              {
+                 if (g->allow)
+                   e_pointer_replay(((Ev_Mouse_Down *)(e->event))->time);
+                 if (g->remove_after)
+                   {
+                      e_button_ungrab(b->win.main, g->button, g->mods, g->any_mod);
+                      free(g);
+                      b->grabs = evas_list_remove(b->grabs, g);
+                      goto again;
+                   }
+              }
+         }
+     }
+     {
+       int act;
+       Ev_Key_Modifiers mods;
+       
+       mods = ((Ev_Mouse_Down *)(current_ev->event))->mods;
+       act = ACT_MOUSE_CLICK;
+       if (((Ev_Mouse_Down *)(current_ev->event))->double_click) act = ACT_MOUSE_DOUBLE;
+       else if (((Ev_Mouse_Down *)(current_ev->event))->triple_click) act = ACT_MOUSE_TRIPLE;
+       e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+       e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+     }
+/*
+ * e_pointer_ungrab(((Ev_Mouse_Up *)(e->event))->time);
+ * e_pointer_replay(((Ev_Mouse_Up *)(e->event))->time);
+ */
+}
+
+static void
+e_cb_border_mouse_up(E_Border *b, Eevent *e)
+{
+   E_Action *a;
+   int x, y, bt;
+   char *class = "Window_Grab";
+   
+   e_pointer_ungrab(CurrentTime);   
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   border_mouse_buttons = mouse_buttons;
+   if (!current_ev) return;
+   x = ((Ev_Mouse_Up *)(e->event))->x;
+   y = ((Ev_Mouse_Up *)(e->event))->y;
+   bt = ((Ev_Mouse_Up *)(e->event))->button;
+     {
+       int act;
+       Ev_Key_Modifiers mods;
+       
+       mods = ((Ev_Mouse_Up *)(current_ev->event))->mods;
+       act = ACT_MOUSE_UP;
+       e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+       e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
+     }
+}
+
+static void
+e_cb_border_mouse_move(E_Border *b, Eevent *e)
+{
+   int dx, dy;
+   int x, y;
+   char *class = "Window_Grab";
+   
+   dx = mouse_x - border_mouse_x;
+   dy = mouse_y - border_mouse_y;
+   border_mouse_x = mouse_x;
+   border_mouse_y = mouse_y;
+   if (!current_ev) return;
+   x = ((Ev_Mouse_Move *)(e->event))->x;
+   y = ((Ev_Mouse_Move *)(e->event))->y;
+   e_action_go(class, ACT_MOUSE_MOVE, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y, dx, dy);
+}
+
+static void
+e_cb_border_move_resize(E_Border *b)
+{
+}
+
+static void
+e_cb_border_visibility(E_Border *b)
+{
+}
+
+static void e_border_poll(int val, void *data)
+{
+   e_add_event_timer("e_border_poll()", 1.00, e_border_poll, val + 1, NULL);
+}
+
+/* border creation, deletion, modification and general queries */
+
+void
+e_border_apply_border(E_Border *b)
+{
+   int pl, pr, pt, pb;
+   
+   if ((!b->client.titlebar) && 
+       (!b->client.border)) e_border_set_bits(b, "../data/borderless.bits.db");
+   else if (b->current.selected) e_border_set_bits(b, "../data/border.bits.db");
+   else                     e_border_set_bits(b, "../data/border2.bits.db");
+
+   pl = pr = pt = pb = 0;
+   if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);   
+   e_icccm_set_frame_size(b->win.client, pl, pr, pt, pb);
+}
+
+E_Border * 
+e_border_adopt(Window win, int use_client_pos)
+{
+   E_Border *b;
+   
+   printf("adopt %x\n", win);
+   /* create the struct */
+   b = e_border_new();
+   /* set the right event on the client */
+   e_window_set_events(win, 
+                      XEV_VISIBILITY | 
+                      ResizeRedirectMask | 
+                      XEV_CONFIGURE | 
+                      XEV_FOCUS | 
+                      XEV_PROPERTY | 
+                      XEV_COLORMAP);
+   /* parent of the client window listens for these */
+   e_window_set_events(b->win.container, XEV_CHILD_CHANGE | XEV_CHILD_REDIRECT);
+   /* add to save set & border of 0 */
+   e_icccm_adopt(win);
+   e_window_set_border_width(win, 0);
+   b->win.client = win;
+   b->current.requested.visible = 1;
+   /* get size & location hints */
+   e_icccm_get_size_info(win, b);
+   e_icccm_get_mwm_hints(win, b);
+   e_icccm_get_layer(win, b);
+   printf("%i\n", b->client.layer);
+   /* desk area */
+   e_icccm_set_desk_area(win, 0, 0);
+   e_icccm_set_desk(win, e_desktops_get_current());
+   if (use_client_pos)
+     {
+       int x, y;
+       
+       e_window_get_geometry(win, &x, &y, NULL, NULL);
+       b->current.requested.x = x;
+       b->current.requested.y = y;
+     }
+   /* reparent the window finally */
+   e_window_reparent(win, b->win.container, 0, 0);
+   /* figure what border to use */
+   e_border_apply_border(b);
+     {
+       int pl, pr, pt, pb;
+        
+       pl = pr = pt = pb = 0;
+       if (b->bits.l) ebits_get_insets(b->bits.l, &pl, &pr, &pt, &pb);
+       b->current.requested.x += pl;
+       b->current.requested.y += pt;
+       b->changed = 1;
+     }
+   /* show the client */
+   e_icccm_state_mapped(win);
+   /* fix size so it matches the hints a client asks for */
+   b->changed = 1;
+   e_border_adjust_limits(b);
+   e_border_raise(b);
+   e_window_show(win);
+   return b;
+}
+
+E_Border *
+e_border_new(void)
+{
+   E_Border *b;
+   int max_colors = 216;
+   int font_cache = 1024 * 1024;
+   int image_cache = 8192 * 1024;
+   char *font_dir = "./fnt";
+   E_Desktop *desk;
+   
+   b = NEW(E_Border, 1);
+   ZERO(b, E_Border, 1);
+   
+   OBJ_INIT(b, e_border_free);
+   
+   b->current.requested.w = 1;
+   b->current.requested.h = 1;
+   b->client.min.w = 1;
+   b->client.min.h = 1;
+   b->client.max.w = 1000000;
+   b->client.max.h = 1000000;
+   b->client.min.aspect = -1000000;
+   b->client.max.aspect = 1000000;
+   b->client.step.w = 1;
+   b->client.step.h = 1;
+   b->client.layer = 4;
+   b->client.border = 1;
+   b->client.handles = 1;
+   b->client.titlebar = 1;
+   
+   desk = e_desktops_get(e_desktops_get_current());
+   e_desktops_add_border(desk, b);
+   b->win.main = e_window_override_new(desk->win.container, 0, 0, 1, 1);
+   b->win.input = e_window_input_new(b->win.main, 0, 0, 1, 1);
+   b->win.container = e_window_override_new(b->win.main, 0, 0, 1, 1);
+   e_window_set_events(b->win.input, XEV_MOUSE_MOVE | XEV_BUTTON | XEV_IN_OUT);
+   e_window_show(b->win.input);
+   e_window_show(b->win.container);
+
+   b->evas.l = evas_new_all(e_display_get(),
+                           b->win.main,
+                           0, 0, 1, 1,
+                           RENDER_METHOD_ALPHA_SOFTWARE,
+                           max_colors,
+                           font_cache, 
+                           image_cache,
+                           font_dir);
+   b->win.l = evas_get_window(b->evas.l);
+   e_add_child(b->win.main, b->win.l);
+   b->evas.r = evas_new_all(e_display_get(),
+                           b->win.main,
+                           0, 0, 1, 1,
+                           RENDER_METHOD_ALPHA_SOFTWARE,
+                           max_colors,
+                           font_cache, 
+                           image_cache,
+                           font_dir);
+   b->win.r = evas_get_window(b->evas.r);
+   e_add_child(b->win.main, b->win.r);
+   b->evas.t = evas_new_all(e_display_get(),
+                           b->win.main,
+                           0, 0, 1, 1,
+                           RENDER_METHOD_ALPHA_SOFTWARE,
+                           max_colors,
+                           font_cache, 
+                           image_cache,
+                           font_dir);
+   b->win.t = evas_get_window(b->evas.t);
+   e_add_child(b->win.main, b->win.t);
+   b->evas.b = evas_new_all(e_display_get(),
+                           b->win.main,
+                           0, 0, 1, 1,
+                           RENDER_METHOD_ALPHA_SOFTWARE,
+                           max_colors,
+                           font_cache, 
+                           image_cache,
+                           font_dir);
+   b->win.b = evas_get_window(b->evas.b); 
+   e_add_child(b->win.main, b->win.b);
+
+   e_window_raise(b->win.input);
+   e_window_raise(b->win.container);
+   
+   evases = evas_list_append(evases, b->evas.l);
+   evases = evas_list_append(evases, b->evas.r);
+   evases = evas_list_append(evases, b->evas.t);
+   evases = evas_list_append(evases, b->evas.b);
+   
+   e_window_set_events(b->win.l, XEV_EXPOSE);
+   e_window_set_events(b->win.r, XEV_EXPOSE);
+   e_window_set_events(b->win.t, XEV_EXPOSE);
+   e_window_set_events(b->win.b, XEV_EXPOSE);
+   
+   e_window_show(b->win.l);
+   e_window_show(b->win.r);
+   e_window_show(b->win.t);
+   e_window_show(b->win.b);
+   
+   e_border_attach_mouse_grabs(b);
+   
+   borders = evas_list_prepend(borders, b);
+   
+   return b;
+}
+
+void
+e_border_free(E_Border *b)
+{
+   Evas_List l;
+
+   e_desktops_del_border(b->desk, b);
+   if (b->bits.l) ebits_free(b->bits.l);
+   if (b->bits.r) ebits_free(b->bits.r);
+   if (b->bits.t) ebits_free(b->bits.t);
+   if (b->bits.b) ebits_free(b->bits.b);
+   evases = evas_list_remove(evases, b->evas.l);
+   evases = evas_list_remove(evases, b->evas.r);
+   evases = evas_list_remove(evases, b->evas.t);
+   evases = evas_list_remove(evases, b->evas.b);
+   evas_free(b->evas.l);
+   evas_free(b->evas.r);
+   evas_free(b->evas.t);
+   evas_free(b->evas.b);
+   e_window_destroy(b->win.container);
+   e_window_destroy(b->win.input);
+   e_window_destroy(b->win.main);
+   borders = evas_list_remove(borders, b);
+   
+   if (b->grabs)
+     {
+       for (l = b->grabs; l; l = l->next)
+         {
+            FREE(l->data);
+         }
+       evas_list_free(b->grabs);
+     }
+   
+   free(b);
+}
+
+void
+e_border_remove_mouse_grabs(E_Border *b)
+{
+   Evas_List l;
+   
+   if (b->grabs)
+     {
+       for (l = b->grabs; l; l = l->next)
+         {
+            E_Grab *g;
+            
+            g = l->data;
+            e_button_ungrab(b->win.main, g->button, g->mods, g->any_mod);
+            FREE(g);
+         }
+       evas_list_free(b->grabs);
+       b->grabs = NULL;
+     }
+}
+
+void
+e_border_attach_mouse_grabs(E_Border *b)
+{
+   char *grabs_db = "./grabs.db";
+   char *settings_db = "./settings.db";
+   E_DB_File *db;
+   int focus_mode;
+   char buf[4096];
+   
+   /* settings - click to focus would affect grabs */
+   db = e_db_open_read(settings_db);   
+   sprintf(buf, "/focus/mode");
+   if ((db) && (e_db_int_get(db, buf, &focus_mode)) && (!b->current.selected))
+     {
+       if (focus_mode == 2) /* click to focus */
+         {
+            E_Grab *g;
+            
+            g = NEW(E_Grab, 1);
+            ZERO(g, E_Grab, 1);
+            g->button = 0;
+            g->mods = 0;
+            g->any_mod = 1;
+            g->remove_after = 1;
+            b->grabs = evas_list_append(b->grabs, g);
+            e_button_grab(b->win.main, 0, XEV_BUTTON | XEV_MOUSE_MOVE, EV_KEY_MODIFIER_NONE, 1);
+            e_db_close(db);
+         }
+     }
+   
+   /* other grabs - liek alt+left to move */
+   db = e_db_open_read(grabs_db);
+   if (db)
+     {
+       int i, num;
+       
+       sprintf(buf, "/grabs/count");
+       if (!e_db_int_get(db, buf, &num))
+         {
+            e_db_close(db);
+            return;
+         }
+       for (i = 0; i < num; i++)
+         {
+            int button, any_mod, mod;
+            Ev_Key_Modifiers mods;
+
+            button = -1;
+            mods = EV_KEY_MODIFIER_NONE;
+            any_mod = 0;
+            sprintf(buf, "/grabs/%i/button", i);
+            if (!e_db_int_get(db, buf, &button)) continue;
+            sprintf(buf, "/grabs/%i/modifiers", i);
+            if (!e_db_int_get(db, buf, &mod)) continue;
+            if (mod == -1) any_mod = 1;
+            mods = (Ev_Key_Modifiers)mod;
+            
+            if (button >= 0)
+              {
+                 E_Grab *g;
+                 
+                 g = NEW(E_Grab, 1);
+                 ZERO(g, E_Grab, 1);
+                 g->button = button;
+                 g->mods = mods;
+                 g->any_mod = any_mod;
+                 g->remove_after = 0;
+                 b->grabs = evas_list_append(b->grabs, g);
+                 e_button_grab(b->win.main, button, XEV_BUTTON | XEV_MOUSE_MOVE, mods, 0);
+              }
+         }
+       e_db_close(db);
+     }
+}
+
+void
+e_border_remove_all_mouse_grabs(void)
+{
+   Evas_List l;
+   
+   for (l = borders; l; l = l->next)
+      e_border_remove_mouse_grabs((E_Border *)l->data);
+}
+
+void
+e_border_attach_all_mouse_grabs(void)
+{
+   Evas_List l;
+   
+   for (l = borders; l; l = l->next)
+      e_border_attach_mouse_grabs((E_Border *)l->data);
+}
+
+void
+e_border_redo_grabs(void)
+{   
+   char *grabs_db = "./grabs.db";
+   char *settings_db = "./settings.db";
+   static time_t mod_date_grabs = 0;
+   static time_t mod_date_settings = 0;
+   time_t mod;
+   int changed = 0;
+   Evas_List l;
+   
+   mod = e_file_modified_time(grabs_db);
+   if (mod != mod_date_grabs) changed = 1;
+   mod_date_grabs = mod;
+   if (!changed)
+     {
+       mod = e_file_modified_time(settings_db);
+       if (mod != mod_date_settings) changed = 1;
+       mod_date_settings = mod;
+     }
+   if (!changed) return;
+   for (l = borders; l; l = l->next)
+     {
+       E_Border *b;
+       
+       b = l->data;
+       e_border_remove_mouse_grabs(b);
+       e_border_attach_mouse_grabs(b);
+     }
+}
+
+E_Border *
+e_border_find_by_window(Window win)
+{
+   Evas_List l;
+   
+   for (l = borders; l; l = l->next)
+     {
+       E_Border *b;
+       
+       b = l->data;
+       
+       if ((win == b->win.main) || 
+           (win == b->win.client) ||
+           (win == b->win.container) ||
+           (win == b->win.input) ||
+           (win == b->win.l) ||
+           (win == b->win.r) ||
+           (win == b->win.t) ||
+           (win == b->win.b))
+         return b;
+     }
+   return NULL;
+}
+
+void
+e_border_set_bits(E_Border *b, char *file)
+{
+   int pl, pr, pt, pb, ppl, ppr, ppt, ppb;
+      
+   pl = pr = pt = pb = 0;
+   ppl = ppr = ppt = ppb = 0;
+   
+   if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
+   
+   if (b->bits.l) ebits_free(b->bits.l);
+   if (b->bits.r) ebits_free(b->bits.r);
+   if (b->bits.t) ebits_free(b->bits.t);
+   if (b->bits.b) ebits_free(b->bits.b);
+
+   b->bits.l = ebits_load(file);
+   b->bits.r = ebits_load(file);
+   b->bits.t = ebits_load(file);
+   b->bits.b = ebits_load(file);
+
+   b->bits.new = 1;
+   b->changed = 1;
+
+   if (b->bits.t) ebits_get_insets(b->bits.l, &ppl, &ppr, &ppt, &ppb);
+   b->current.requested.w -= (pl + pr) - (ppl + ppr);
+   b->current.requested.h -= (pt + pb) - (ppt + ppb);
+   b->current.requested.x += (pl - ppl);
+   b->current.requested.y += (pt - ppt);
+   
+   if (b->bits.t)
+     {
+       ebits_add_to_evas(b->bits.l, b->evas.l);
+       ebits_move(b->bits.l, 0, 0);
+       ebits_show(b->bits.l);
+
+       ebits_add_to_evas(b->bits.r, b->evas.r);
+       ebits_move(b->bits.r, 0, 0);
+       ebits_show(b->bits.r);
+
+       ebits_add_to_evas(b->bits.t, b->evas.t);
+       ebits_move(b->bits.t, 0, 0);
+       ebits_show(b->bits.t);
+
+       ebits_add_to_evas(b->bits.b, b->evas.b);
+       ebits_move(b->bits.b, 0, 0);
+       ebits_show(b->bits.b);
+       
+       e_border_set_color_class(b, "Title BG", 100, 200, 255, 255);
+
+#define HOOK_CB(_class)        \
+ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_IN, e_cb_mouse_in, b); \
+ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_OUT, e_cb_mouse_out, b); \
+ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_DOWN, e_cb_mouse_down, b); \
+ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_UP, e_cb_mouse_up, b); \
+ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_MOVE, e_cb_mouse_move, b);
+       HOOK_CB("Title_Bar");
+       HOOK_CB("Resize");
+       HOOK_CB("Resize_Horizontal");
+       HOOK_CB("Resize_Vertical");
+       HOOK_CB("Close");
+       HOOK_CB("Iconify");
+       HOOK_CB("Max_Size");
+       HOOK_CB("Menu");
+       
+       e_border_adjust_limits(b);
+     }
+}
+
+void
+e_border_set_color_class(E_Border *b, char *class, int rr, int gg, int bb, int aa)
+{
+   ebits_set_color_class(b->bits.l, class, rr, gg, bb, aa);
+   ebits_set_color_class(b->bits.r, class, rr, gg, bb, aa);
+   ebits_set_color_class(b->bits.t, class, rr, gg, bb, aa);
+   ebits_set_color_class(b->bits.b, class, rr, gg, bb, aa);
+}
+
+void
+e_border_adjust_limits(E_Border *b)
+{
+   int w, h, pl, pr, pt, pb, mx, my;
+
+   if (b->mode.move) e_resist_border(b);
+   else
+     {
+        b->current.x = b->current.requested.x;
+       b->current.y = b->current.requested.y;
+     }
+   
+   b->current.w = b->current.requested.w;
+   b->current.h = b->current.requested.h;
+      
+   pl = pr = pt = pb = 0;
+   if (b->current.w < 1) b->current.w = 1;
+   if (b->current.h < 1) b->current.h = 1;
+       
+   if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
+
+   if (b->current.w < (pl + pr + 1)) b->current.w = pl + pr + 1;
+   if (b->current.h < (pt + pb + 1)) b->current.h = pt + pb + 1;
+   
+   w = b->current.w - pl - pr;
+   h = b->current.h - pt - pb;
+   
+   mx = my = 1;
+   if (b->bits.t) ebits_get_min_size(b->bits.t, &mx, &my);     
+   if (b->current.w < mx) b->current.w = mx;
+   if (b->current.h < my) b->current.h = my;
+   mx = my = 999999;
+   if (b->bits.t) ebits_get_max_size(b->bits.t, &mx, &my);     
+   if (b->current.w > mx) b->current.w = mx;
+   if (b->current.h > my) b->current.h = my;
+
+   if (w < b->client.min.w) w = b->client.min.w;
+   if (h < b->client.min.h) h = b->client.min.h;
+   if (w > b->client.max.w) w = b->client.max.w;
+   if (h > b->client.max.h) h = b->client.max.h;
+   if ((w > 0) && (h > 0))
+     {
+       w -= b->client.base.w;
+       h -= b->client.base.h;
+       if ((w > 0) && (h > 0))
+         {
+            int i, j;
+            double aspect;
+            
+            aspect = ((double)w) / ((double)h);
+            if ((b->mode.resize == 4) || (b->mode.resize == 5))
+              {
+                 if (aspect < b->client.min.aspect)
+                   h = (int)((double)w / b->client.min.aspect);
+                 if (aspect > b->client.max.aspect)
+                   h = (int)((double)w / b->client.max.aspect);
+              }
+            else if ((b->mode.resize == 6) || (b->mode.resize == 7))
+              {
+                 if (aspect < b->client.min.aspect)
+                   w = (int)((double)h * b->client.min.aspect);
+                 if (aspect > b->client.max.aspect)
+                   w = (int)((double)h * b->client.max.aspect);
+              }
+            else
+              {
+                 if (aspect < b->client.min.aspect)
+                   w = (int)((double)h * b->client.min.aspect);
+                 if (aspect > b->client.max.aspect)
+                   h = (int)((double)w / b->client.max.aspect);
+              }
+            i = w / b->client.step.w;
+            j = h / b->client.step.h;
+            w = i * b->client.step.w;
+            h = j * b->client.step.h;
+         }
+       w += b->client.base.w;
+       h += b->client.base.h;
+     }
+   b->current.w = w + pl + pr;
+   b->current.h = h + pt + pb;
+   
+   if ((b->mode.resize == 3) || (b->mode.resize == 5) || (b->mode.resize == 7))
+     {
+     }
+   else if ((b->mode.resize == 0) || (b->mode.resize == 4))
+     {
+       b->current.x += (b->current.requested.w - b->current.w);
+       b->current.y += (b->current.requested.h - b->current.h);
+     }
+   else if ((b->mode.resize == 1) || (b->mode.resize == 6))
+     {
+       b->current.y += (b->current.requested.h - b->current.h);
+     }
+   else if ((b->mode.resize == 2))
+     {
+       b->current.x += (b->current.requested.w - b->current.w);
+     }
+}
+
+void
+e_border_update(E_Border *b)
+{
+   int location_changed = 0;
+   int size_changed = 0;
+   int shape_changed = 0;
+   int border_changed = 0;
+   int visibility_changed = 0;
+   int state_changed = 0;
+   
+   if (!b->changed) return;
+   
+   b->current.visible = b->current.requested.visible;
+   
+   if ((b->current.x != b->previous.x) || (b->current.y != b->previous.y))
+     location_changed = 1;
+   if ((b->current.w != b->previous.w) || (b->current.h != b->previous.h))
+     size_changed = 1;
+   if ((size_changed) && (b->has_shape))
+     shape_changed = 1;
+   if (b->bits.new)
+     {
+       e_window_gravity_set(b->win.container, StaticGravity);
+       border_changed = 1;
+     }
+   if ((border_changed) && (b->has_shape))
+     shape_changed = 1;
+   if (b->current.visible != b->previous.visible)
+     visibility_changed = 1;
+   if (b->current.selected != b->previous.selected)
+      state_changed = 1;
+   
+   if (state_changed)
+     {
+       e_border_apply_border(b);
+       if (!border_changed)
+         {
+            e_window_gravity_set(b->win.container, StaticGravity);
+            border_changed = 1;
+            size_changed = 1;
+         }
+     }
+   if ((location_changed) && (!size_changed))
+     {
+       int pl, pr, pt, pb;
+       
+       e_window_move(b->win.main, b->current.x, b->current.y);
+       pl = pr = pt = pb = 0;
+       if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
+       e_icccm_move_resize(b->win.client, 
+                           b->current.x + pl, b->current.y + pt, 
+                           b->current.w - pl - pr, b->current.h - pt - pb);
+       e_cb_border_move_resize(b);
+     }
+   else if (size_changed)
+     {
+       int pl, pr, pt, pb, x, y, w, h;
+       int smaller;
+       
+       smaller = 0;
+       if ((b->current.w < b->previous.w) || (b->current.h < b->previous.h))
+          smaller = 1;
+       pl = pr = pt = pb = 0;
+       if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
+       e_window_resize(b->win.client, b->current.w - pl - pr, b->current.h - pt - pb);
+       e_window_move_resize(b->win.input, 
+                            0, 0, b->current.w, b->current.h);
+       e_window_move_resize(b->win.main, 
+                            b->current.x, b->current.y,
+                            b->current.w, b->current.h);
+       e_window_move_resize(b->win.container, pl, pt,
+                            b->current.w - pl - pr, b->current.h - pt -pb);
+       x = 0, y = pt, w = pl, h = (b->current.h - pt - pb);
+       e_window_move_resize(b->win.l, x, y, w, h);
+       evas_set_output_size(b->evas.l, w, h);
+       evas_set_output_viewport(b->evas.l, x, y, w, h);
+       
+       x = 0, y = 0, w = b->current.w, h = pt;
+       e_window_move_resize(b->win.t, x, y, w, h);
+       evas_set_output_size(b->evas.t, w, h);
+       evas_set_output_viewport(b->evas.t, x, y, w, h);
+       
+       x = b->current.w - pr, y = pt, w = pr, h = (b->current.h - pt - pb);
+       e_window_move_resize(b->win.r, x, y, w, h);
+       evas_set_output_size(b->evas.r, w, h);
+       evas_set_output_viewport(b->evas.r, x, y, w, h);
+       
+       x = 0, y = b->current.h - pb, w = b->current.w, h = pb;
+       e_window_move_resize(b->win.b, x, y, w, h);
+       evas_set_output_size(b->evas.b, w, h);
+       evas_set_output_viewport(b->evas.b, x, y, w, h);
+
+       if (b->bits.l) ebits_resize(b->bits.l, b->current.w, b->current.h);
+       if (b->bits.r) ebits_resize(b->bits.r, b->current.w, b->current.h);
+       if (b->bits.t) ebits_resize(b->bits.t, b->current.w, b->current.h);
+       if (b->bits.b) ebits_resize(b->bits.b, b->current.w, b->current.h);
+       
+       e_icccm_move_resize(b->win.client, 
+                           b->current.x + pl, b->current.y + pt, 
+                           b->current.w - pl - pr, b->current.h - pt - pb);
+       e_cb_border_move_resize(b);
+     }
+   if (visibility_changed)
+     {
+       if (b->current.visible)
+         e_window_show(b->win.main);
+       else
+         e_window_hide(b->win.main);
+       e_cb_border_visibility(b);
+     }
+
+   if (border_changed)
+     e_window_gravity_set(b->win.container, NorthWestGravity);
+   b->bits.new = 0;   
+   b->previous = b->current;   
+   b->changed = 0;
+}
+
+void
+e_border_set_layer(E_Border *b, int layer)
+{
+   Evas_List l;
+   E_Border *rel = NULL;
+   int dl;
+   
+   if (b->client.layer == layer) return;
+   dl = layer - b->client.layer;
+   b->client.layer = layer;
+   if (dl > 0) e_border_lower(b);
+   else  e_border_raise(b);
+}
+
+void
+e_border_raise(E_Border *b)
+{
+   Evas_List l;
+   E_Border *rel;
+   
+   if (!b->desk->windows)
+     {
+       b->desk->windows = evas_list_append(b->desk->windows, b);
+       b->desk->changed = 1;
+       e_window_raise(b->win.main);
+       return;
+     }
+   for (l = b->desk->windows; l; l = l->next)
+     {
+       rel = l->data;
+       if (rel->client.layer > b->client.layer)
+         {
+            b->desk->windows = evas_list_remove(b->desk->windows, b);
+            b->desk->windows = evas_list_prepend_relative(b->desk->windows, b, rel);
+            b->desk->changed = 1;
+            e_window_stack_below(b->win.main, rel->win.main);
+            return;
+         }
+       if ((!l->next) && (l->data != b))
+         {
+            b->desk->windows = evas_list_remove(b->desk->windows, b);
+            b->desk->windows = evas_list_append(b->desk->windows, b);
+            b->desk->changed = 1;
+            e_window_raise(b->win.main);
+            return;
+         }
+     }
+}
+
+void
+e_border_lower(E_Border *b)
+{
+   Evas_List l;
+   E_Border *rel;
+   
+   if (!b->desk->windows)
+     {
+       b->desk->windows = evas_list_append(b->desk->windows, b);
+       b->desk->changed = 1;
+       e_window_raise(b->win.main);
+       return;
+     }
+   for (l = b->desk->windows; l; l = l->next)
+     {
+       rel = l->data;
+       if (rel->client.layer == b->client.layer)
+         {
+            if (b == rel) return;
+            b->desk->windows = evas_list_remove(b->desk->windows, b);
+            b->desk->windows = evas_list_prepend_relative(b->desk->windows, b, rel);
+            b->desk->changed = 1;
+            e_window_stack_below(b->win.main, rel->win.main);
+            return;
+         }
+     }
+}
+
+void
+e_border_raise_above(E_Border *b, E_Border *above)
+{
+   if (!b->desk->windows)
+     {
+       b->desk->windows = evas_list_append(b->desk->windows, b);
+       b->desk->changed = 1;
+       e_window_raise(b->win.main);
+       return;
+     }
+   if (!evas_list_find(b->desk->windows, above)) return;
+   if (b->client.layer < above->client.layer) b->client.layer = above->client.layer;
+   b->desk->windows = evas_list_remove(b->desk->windows, b);
+   b->desk->windows = evas_list_append_relative(b->desk->windows, b, above);
+   b->desk->changed = 1;
+   e_window_stack_above(b->win.main, above->win.main);
+}
+
+void
+e_border_lower_below(E_Border *b, E_Border *below)
+{
+   if (!b->desk->windows)
+     {
+       b->desk->windows = evas_list_append(b->desk->windows, b);
+       b->desk->changed = 1;
+       return;
+     }
+   if (!evas_list_find(b->desk->windows, below)) return;
+   if (b->client.layer > below->client.layer) b->client.layer = below->client.layer;
+   b->desk->windows = evas_list_remove(b->desk->windows, b);
+   b->desk->windows = evas_list_prepend_relative(b->desk->windows, b, below);
+   b->desk->changed = 1;
+   e_window_stack_below(b->win.main, below->win.main);
+}
+
+void
+e_border_init(void)
+{
+   e_event_filter_handler_add(EV_MOUSE_DOWN,               e_mouse_down);
+   e_event_filter_handler_add(EV_MOUSE_UP,                 e_mouse_up);
+   e_event_filter_handler_add(EV_MOUSE_MOVE,               e_mouse_move);
+   e_event_filter_handler_add(EV_MOUSE_IN,                 e_mouse_in);
+   e_event_filter_handler_add(EV_MOUSE_OUT,                e_mouse_out);
+   e_event_filter_handler_add(EV_WINDOW_EXPOSE,            e_window_expose);
+   e_event_filter_handler_add(EV_WINDOW_MAP_REQUEST,       e_map_request);
+   e_event_filter_handler_add(EV_WINDOW_CONFIGURE_REQUEST, e_configure_request);
+   e_event_filter_handler_add(EV_WINDOW_PROPERTY,          e_property);
+   e_event_filter_handler_add(EV_WINDOW_UNMAP,             e_unmap);
+   e_event_filter_handler_add(EV_WINDOW_DESTROY,           e_destroy);
+   e_event_filter_handler_add(EV_WINDOW_CIRCULATE_REQUEST, e_circulate_request);
+   e_event_filter_handler_add(EV_WINDOW_REPARENT,          e_reparent);
+   e_event_filter_handler_add(EV_WINDOW_SHAPE,             e_shape);
+   e_event_filter_handler_add(EV_WINDOW_FOCUS_IN,          e_focus_in);
+   e_event_filter_handler_add(EV_WINDOW_FOCUS_OUT,         e_focus_out);
+   e_event_filter_handler_add(EV_COLORMAP,                 e_colormap);
+   e_event_filter_idle_handler_add(e_idle, NULL);
+
+   e_add_event_timer("e_border_poll()", 1.00, e_border_poll, 0, NULL);
+}
+
+void
+e_border_adopt_children(Window win)
+{
+   Window *wins;
+   int i, num;
+
+   wins = e_window_get_children(win, &num);
+   if (wins)
+     {
+       for (i = 0; i < num; i++)
+         {
+            if (e_window_is_manageable(wins[i])) 
+              {
+                 E_Border *b;
+                 
+                 printf("manage %x\n", wins[i]);
+                 b = e_border_adopt(wins[i], 1);
+                   {
+                      int pl, pr, pt, pb;
+                      
+                      pl = pr = pt = pb = 0;
+                      if (b->bits.l) ebits_get_insets(b->bits.l, &pl, &pr, &pt, &pb);
+                      b->current.requested.x -= pl;
+                      b->current.requested.y -= pt;
+                      printf("back %i %i\n", pl, pt);
+                      b->changed = 1;
+                      e_border_adjust_limits(b);
+                   }
+                 b->ignore_unmap = 2;
+              }
+         }
+       free(wins);
+     }
+}
diff --git a/src/desktops.c b/src/desktops.c
new file mode 100644 (file)
index 0000000..74dc908
--- /dev/null
@@ -0,0 +1,508 @@
+#include "e.h"
+
+static Evas_List desktops = NULL;
+static Window    e_base_win = 0;
+static int       screen_w, screen_h;
+static int       current_desk = 0;
+
+static void e_idle(void *data);
+static void e_mouse_down(Eevent * ev);
+static void e_mouse_up(Eevent * ev);
+static void e_mouse_in(Eevent * ev);
+static void e_mouse_out(Eevent * ev);
+static void e_window_expose(Eevent * ev);
+
+static void
+e_idle(void *data)
+{
+   Evas_List l;
+   
+   for (l = desktops; l; l = l->next)
+     {
+       E_Desktop *desk;
+       
+       desk = l->data;
+       e_desktops_update(desk);
+     }
+   e_db_runtime_flush();
+}
+
+/* handling mouse down events */
+static void 
+e_mouse_down(Eevent * ev)
+{
+   Ev_Mouse_Down      *e;
+   
+   e = ev->event;
+     {
+       Evas_List l;
+       
+       for (l = desktops; l; l = l->next)
+         {
+            E_Desktop *desk;
+            
+            desk = l->data;
+            
+            if (desk->win.desk == e->win)
+              {
+                 Evas evas;
+                 int x, y;
+                 
+                 evas = desk->evas.desk;
+                 e_window_get_root_relative_location(evas_get_window(evas),
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_down(evas, x, y, e->button);
+                 return;
+              }
+         }
+     }
+}
+/* handling mouse up events */
+static void
+e_mouse_up(Eevent * ev)
+{
+   Ev_Mouse_Up      *e;
+   
+   e = ev->event;
+     {
+       Evas_List l;
+       
+       for (l = desktops; l; l = l->next)
+         {
+            E_Desktop *desk;
+            
+            desk = l->data;
+            
+            if (desk->win.desk == e->win)
+              {
+                 Evas evas;
+                 int x, y;
+                 
+                 evas = desk->evas.desk;
+                 e_window_get_root_relative_location(evas_get_window(evas),
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_button_up(evas, x, y, e->button);
+                 return;
+              }
+         }
+     }
+}
+/* handling mouse move events */
+static void
+e_mouse_move(Eevent * ev)
+{
+   Ev_Mouse_Move      *e;
+   
+   e = ev->event;
+     {
+       Evas_List l;
+       
+       for (l = desktops; l; l = l->next)
+         {
+            E_Desktop *desk;
+            
+            desk = l->data;
+            
+            if (desk->win.desk == e->win)
+              {
+                 Evas evas;
+                 int x, y;
+                 
+                 evas = desk->evas.desk;
+                 e_window_get_root_relative_location(evas_get_window(evas),
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 return;
+              }
+         }
+     }
+}
+
+/* handling mouse enter events */
+static void
+e_mouse_in(Eevent * ev)
+{
+   Ev_Window_Enter      *e;
+   
+   e = ev->event;
+     {
+       Evas_List l;
+       
+       for (l = desktops; l; l = l->next)
+         {
+            E_Desktop *desk;
+            
+            desk = l->data;
+            
+            if (desk->win.desk == e->win)
+              {
+                 Evas evas;
+                 int x, y;
+                 
+                 evas = desk->evas.desk;
+                 e_window_get_root_relative_location(evas_get_window(evas),
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas_event_enter(evas);
+                 return;
+              }
+         }
+     }
+}
+/* handling mouse leave events */
+static void
+e_mouse_out(Eevent * ev)
+{
+   Ev_Window_Leave      *e;
+   
+   e = ev->event;
+     {
+       Evas_List l;
+       
+       for (l = desktops; l; l = l->next)
+         {
+            E_Desktop *desk;
+            
+            desk = l->data;
+            
+            if (desk->win.desk == e->win)
+              {
+                 Evas evas;
+                 int x, y;
+                 
+                 evas = desk->evas.desk;
+                 e_window_get_root_relative_location(evas_get_window(evas),
+                                                     &x, &y);
+                 x = e->rx - x;
+                 y = e->ry - y;
+                 evas_event_move(evas, x, y);
+                 evas_event_leave(evas);
+                 return;
+              }
+         }
+     }
+}
+
+/* handling expose events */
+static void
+e_window_expose(Eevent * ev)
+{
+   Ev_Window_Expose      *e;
+   
+   e = ev->event;
+     {
+       Evas_List l;
+       
+       for (l = desktops; l; l = l->next)
+         {
+            E_Desktop *desk;
+            
+            desk = l->data;
+            if (!desk->evas.pmap)
+              {
+                 if (evas_get_window(desk->evas.desk) == e->win)
+                   evas_update_rect(desk->evas.desk, e->x, e->y, e->w, e->h);
+              }
+         }
+     }
+}
+
+void
+e_desktops_init(void)
+{
+   E_Desktop *desk;
+   
+   e_window_get_geometry(0, NULL, NULL, &screen_w, &screen_h);
+   e_base_win = e_window_override_new(0, 0, 0, screen_w, screen_h);
+   e_window_show(e_base_win);
+   desk = e_desktops_new();
+   e_desktops_show(desk);
+   e_event_filter_handler_add(EV_MOUSE_DOWN,               e_mouse_down);
+   e_event_filter_handler_add(EV_MOUSE_UP,                 e_mouse_up);
+   e_event_filter_handler_add(EV_MOUSE_MOVE,               e_mouse_move);
+   e_event_filter_handler_add(EV_MOUSE_IN,                 e_mouse_in);
+   e_event_filter_handler_add(EV_MOUSE_OUT,                e_mouse_out);
+   e_event_filter_handler_add(EV_WINDOW_EXPOSE,            e_window_expose);
+   e_event_filter_idle_handler_add(e_idle, NULL);
+   e_icccm_advertise_e_compat();
+   e_icccm_advertise_mwm_compat();
+   e_icccm_advertise_gnome_compat();
+   e_icccm_advertise_kde_compat();
+   e_icccm_advertise_net_compat();
+   
+   e_icccm_set_desk_area_size(0, 1, 1);
+   e_icccm_set_desk_area(0, 0, 0);
+   e_icccm_set_desk(0, 0);
+}
+
+void
+e_desktops_scroll(E_Desktop *desk, int dx, int dy)
+{
+   Evas_List l;
+   int xd, yd, wd, hd;
+   int grav, grav_stick;   
+   
+   /* set grav */
+   if ((dx ==0) && (dy == 0)) return;
+   desk->x -= dx;
+   desk->y -= dy;
+   xd = yd = wd = hd = 0;
+   grav = NorthWestGravity;
+   grav_stick= SouthEastGravity;
+   if ((dx <= 0) && (dy <= 0))
+     {
+       grav = NorthWestGravity;
+       grav_stick = SouthEastGravity;
+       xd = dx;
+       yd = dy;
+       wd = -dx;
+       hd = -dy;
+     }
+   else if ((dx >= 0) && (dy <= 0))
+     {
+       grav = NorthEastGravity;
+       grav_stick = SouthWestGravity;
+       xd = 0;
+       yd = dy;
+       wd = dx;
+       hd = -dy;
+     }
+   else if ((dx >= 0) && (dy >= 0))
+     {
+       grav = SouthEastGravity;
+       grav_stick = NorthWestGravity;
+       xd = 0;
+       yd = 0;
+       wd = dx;
+       hd = dy;
+     }
+   else if ((dx <= 0) && (dy >= 0))
+     {
+       grav = SouthWestGravity;
+       grav_stick = NorthEastGravity;
+       xd = dx;
+       yd = 0;
+       wd = -dx;
+       hd = dy;
+     }
+   for (l = desk->windows; l; l = l->next)
+     {
+       E_Border *b;
+       
+       b = l->data;
+       /* if sticky */
+/*     e_window_gravity_set(b->win.main, StaticGravity); */
+       e_window_gravity_set(b->win.main, grav);        
+     }
+   grav_stick = StaticGravity;
+   e_window_gravity_set(desk->win.desk, grav_stick);
+   /* scroll */
+   e_window_move_resize(desk->win.container, 
+                       xd, yd, 
+                       screen_w + wd, screen_h + hd);
+   /* reset */
+   for (l = desk->windows; l; l = l->next)
+     {
+       E_Border *b;
+       
+       b = l->data;
+       e_window_gravity_set(b->win.main, grav_stick);
+     }   
+   e_window_move_resize(desk->win.container, 0, 0, screen_w, screen_h);
+   e_window_gravity_reset(desk->win.desk);
+   for (l = desk->windows; l; l = l->next)
+     {
+       E_Border *b;
+       
+       b = l->data;
+       e_window_gravity_reset(b->win.main);
+       b->current.requested.x += dx;
+       b->current.requested.y += dy;
+       b->current.x = b->current.requested.x;
+       b->current.y = b->current.requested.y;
+       b->previous.requested.x = b->current.requested.x;
+       b->previous.requested.y = b->current.requested.y;
+       b->previous.x = b->current.x;
+       b->previous.y = b->current.y;
+       b->changed = 1;
+     }
+   e_sync();
+}
+
+void
+e_desktops_free(E_Desktop *desk)
+{
+   e_window_destroy(desk->win.main);
+   IF_FREE(desk->name);
+   IF_FREE(desk->dir);
+   FREE(desk);
+}
+
+void
+e_desktops_init_file_display(E_Desktop *desk)
+{
+   int max_colors = 216;
+   int font_cache = 1024 * 1024;
+   int image_cache = 8192 * 1024;
+   char *font_dir = "./fnt";
+   
+   /* software */
+   desk->evas.desk = evas_new_all(e_display_get(),
+                                 desk->win.container,
+                                 0, 0, screen_w, screen_h,
+                                 RENDER_METHOD_ALPHA_SOFTWARE,
+                                 max_colors,
+                                 font_cache,
+                                 image_cache,
+                                 font_dir);
+   desk->win.desk = evas_get_window(desk->evas.desk);
+   e_add_child(desk->win.container, desk->win.desk);
+   /* pixmap backing for desktop */
+   desk->evas.pmap = e_pixmap_new(desk->win.desk, screen_w, screen_h, 0);
+   evas_set_output(desk->evas.desk, e_display_get(), desk->evas.pmap, 
+                  evas_get_visual(desk->evas.desk), evas_get_colormap(desk->evas.desk));
+   e_window_set_background_pixmap(desk->win.desk, desk->evas.pmap);
+   /* normal stuff */
+   e_window_set_events(desk->win.desk, XEV_EXPOSE | XEV_MOUSE_MOVE | XEV_BUTTON | XEV_IN_OUT); 
+   e_window_show(desk->win.desk);
+     {
+       Evas_Object o;
+       Evas e;
+       
+       e = desk->evas.desk;
+       o = evas_add_image_from_file(e, "../data/bg.png");
+       evas_move(e, o, 0, 0);
+       evas_resize(e, o, screen_w, screen_h);
+       evas_show(e, o);
+       o = evas_add_image_from_file(e, "../data/e_logo.png");
+       evas_move(e, o, 0, 0);
+       evas_show(e, o);
+     }   
+}
+
+E_Desktop *
+e_desktops_new(void)
+{
+   E_Desktop *desk;
+   
+   desk = NEW(E_Desktop, 1);
+   ZERO(desk, E_Desktop, 1);
+   
+   OBJ_INIT(desk, e_desktops_free);
+   
+   desk->win.main = e_window_override_new(e_base_win, 0, 0, screen_w, screen_h);
+   desk->win.container = e_window_override_new(desk->win.main, 0, 0, screen_w, screen_h);
+   
+   e_window_show(desk->win.container);
+
+   desk->x = 0;
+   desk->y = 0;
+   desk->real.w = screen_w;
+   desk->real.h = screen_h;
+   desk->virt.w = screen_w;
+   desk->virt.h = screen_h;
+   
+   desktops = evas_list_append(desktops, desk);
+   
+   e_desktops_init_file_display(desk);
+   
+   return desk;
+}
+
+void
+e_desktops_add_border(E_Desktop *d, E_Border *b)
+{
+   if ((!d) || (!b)) return;
+   b->desk = d;
+   e_border_raise(b);
+}
+
+void
+e_desktops_del_border(E_Desktop *d, E_Border *b)
+{
+   if ((!d) || (!b)) return;
+   d->windows = evas_list_remove(d->windows, b);
+   b->desk = NULL;
+}
+
+void
+e_desktops_delete(E_Desktop *d)
+{
+   OBJ_DO_FREE(d);
+}
+
+void
+e_desktops_show(E_Desktop *d)
+{
+   e_window_show(d->win.main);
+}
+
+void
+e_desktops_hide(E_Desktop *d)
+{
+   e_window_hide(d->win.main);
+}
+
+int
+e_desktops_get_num(void)
+{
+   Evas_List l;
+   int i;
+   
+   for (i = 0, l = desktops; l; l = l->next, i++);
+   return i;
+}
+
+E_Desktop *
+e_desktops_get(int d)
+{
+   Evas_List l;
+   int i;
+   
+   for (i = 0, l = desktops; l; l = l->next, i++)
+     {
+       if (i == d) return (E_Desktop *)l->data;
+     }
+   return NULL;
+}
+
+int
+e_desktops_get_current(void)
+{
+   return current_desk;
+}
+
+void
+e_desktops_update(E_Desktop *desk)
+{
+   Imlib_Updates up;
+   
+   up = evas_render_updates(desk->evas.desk);
+   if (up)
+     {
+       Imlib_Updates u;
+       
+       printf("rendered desktop\n");
+       for (u = up; u; u = imlib_updates_get_next(u))
+         {
+            int x, y, w, h;
+            
+            imlib_updates_get_coordinates(u, &x, &y, &w, &h);
+            e_window_clear_area(desk->win.desk, x, y, w, h);
+         }
+       imlib_updates_free(up);
+     }
+   if (desk->changed)
+     {
+       desk->changed = 0;
+     }
+}
diff --git a/src/e.h b/src/e.h
new file mode 100644 (file)
index 0000000..41565f7
--- /dev/null
+++ b/src/e.h
@@ -0,0 +1,337 @@
+#include <X11/Xlib.h>
+#include <Imlib2.h>
+#include <Evas.h>
+#include <Ebits.h>
+#include <Ecore.h>
+#include <Edb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <dirent.h>
+#include <errno.h>
+#include <signal.h>
+
+#define E_PROF 1
+#ifdef E_PROF
+extern Evas_List __e_profiles;
+
+typedef struct _e_prof
+{
+   char  *func;
+   double total;
+   double t1, t2;
+} E_Prof;
+#define E_PROF_START(_prof_func) \
+{ \
+E_Prof __p, *__pp; \
+Evas_List __pl; \
+__p.func = _prof_func; \
+__p.total = 0.0; \
+__p.t1 = e_get_time(); \
+__p.t2 = 0.0;
+
+#define E_PROF_STOP \
+__p.t2 = e_get_time(); \
+for (__pl = __e_profiles; __pl; __pl = __pl->next) \
+{ \
+__pp = __pl->data; \
+if (!strcmp(__p.func, __pp->func)) \
+{ \
+__pp->total += (__p.t2 - __p.t1); \
+break; \
+} \
+} \
+if (!__pl) \
+{ \
+__pp = NEW(E_Prof, 1); \
+__pp->func = __p.func; \
+__pp->total = __p.t2 - __p.t1; \
+__pp->t1 = 0.0; \
+__pp->t2 = 0.0; \
+__e_profiles = evas_list_append(__e_profiles, __pp); \
+} \
+}
+#define E_PROF_DUMP \
+{ \
+Evas_List __pl; \
+for (__pl = __e_profiles; __pl; __pl = __pl->next) \
+{ \
+E_Prof *__p; \
+__p = __pl->data; \
+printf("%3.3f : %s()\n", __p->total, __p->func); \
+} \
+}
+#else
+#define E_PROF_START(_prof_func)
+#define E_PROF_STOP
+#define E_PROF_DUMP
+#endif
+
+
+#define OBJ_REF(_e_obj) _e_obj->references++
+#define OBJ_UNREF(_e_obj) _e_obj->references--;
+#define OBJ_IF_FREE(_e_obj) if (_e_obj->references == 0)
+#define OBJ_FREE(_e_obj) _e_obj->e_obj_free(_e_obj)
+#define OBJ_DO_FREE(_e_obj) \
+OBJ_UNREF(_e_obj); \
+OBJ_IF_FREE(_e_obj) \
+{ \
+OBJ_FREE(_e_obj); \
+}
+
+#define OBJ_PROPERTIES \
+int references; \
+void (*e_obj_free) (void *e_obj);
+#define OBJ_INIT(_e_obj, _e_obj_free_func) \
+{ \
+_e_obj->references = 1; \
+_e_obj->e_obj_free = (void *) _e_obj_free_func; \
+}
+
+#define SPANS_COMMON(x1, w1, x2, w2) \
+  (!((((x2) + (w2)) <= (x1)) || ((x2) >= ((x1) + (w1)))))
+
+#define ACT_MOUSE_IN      0
+#define ACT_MOUSE_OUT     1
+#define ACT_MOUSE_CLICK   2
+#define ACT_MOUSE_DOUBLE  3
+#define ACT_MOUSE_TRIPLE  4
+#define ACT_MOUSE_UP      5
+#define ACT_MOUSE_CLICKED 6
+#define ACT_MOUSE_MOVE    7
+#define ACT_KEY_DOWN      8
+#define ACT_KEY_UP        9
+
+#define SET_BORDER_GRAVITY(_b, _grav) \
+e_window_gravity_set(_b->win.container, _grav); \
+e_window_gravity_set(_b->win.input, _grav); \
+e_window_gravity_set(_b->win.l, _grav); \
+e_window_gravity_set(_b->win.r, _grav); \
+e_window_gravity_set(_b->win.t, _grav); \
+e_window_gravity_set(_b->win.b, _grav);
+
+typedef struct _E_Object       E_Object;
+typedef struct _E_Border       E_Border;
+typedef struct _E_Grab         E_Grab;
+typedef struct _E_Action       E_Action;
+typedef struct _E_Action_Proto E_Action_Proto;
+typedef struct _E_Desktop      E_Desktop;
+typedef struct _E_Rect          E_Rect;
+
+struct _E_Object
+{
+   OBJ_PROPERTIES;
+};
+
+struct _E_Border
+{
+   OBJ_PROPERTIES;
+
+   struct {
+      Window main;
+      Window l, r, t, b;
+      Window input;
+      Window container;
+      Window client;
+   } win;
+   struct {
+      Evas l, r, t, b;
+   } evas;
+   struct {
+      Pixmap l, r, t, b;
+   } pixmap;
+   struct {
+      int new;
+      Ebits_Object l, r, t, b;
+   } bits;
+   
+   struct {
+      struct {
+        int x, y, w, h;
+        int visible;
+        int dx, dy;
+      } requested;
+      int   x, y, w, h;
+      int   visible;
+      int   selected;
+   } current, previous;
+   
+   struct {
+      struct {
+        int w, h;
+        double aspect;
+      } base, min, max, step;
+      int layer;
+      int shaped;
+      char *title;
+      char *name;
+      char *class;
+      char *command;
+      Window group;
+      int sticky;
+      Colormap colormap;
+      int fixed;
+      int arrange_ignore;
+      int shaded;
+      int hidden;
+      int borderless;
+      int titlebar;
+      int border;
+      int handles;
+   } client;
+   
+   struct {
+      int move, resize;
+   } mode;
+   
+   int has_shape;
+   int shape_changes;
+   
+   int ignore_unmap;
+   
+   Evas_List grabs;
+   E_Desktop *desk;
+   
+   int changed;
+};
+
+struct _E_Grab
+{
+   int              button;
+   Ev_Key_Modifiers mods;
+   int              any_mod;
+   int              remove_after;
+   int              allow;
+};
+
+struct _E_Action
+{
+   OBJ_PROPERTIES;
+   
+   char           *name;
+   char           *action;
+   char           *params;
+   int             event;
+   int             button;
+   char           *key;
+   int             modifiers;
+   E_Action_Proto *action_proto;
+   void           *object;
+   int             started;
+};
+
+struct _E_Action_Proto
+{
+   OBJ_PROPERTIES;
+   
+   char  *action;
+   void (*func_start) (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+   void (*func_stop)  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry);
+   void (*func_go)    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy);
+};
+
+struct _E_Desktop
+{
+   OBJ_PROPERTIES;
+   
+   char *name;
+   char *dir;
+   struct {
+      Window main;
+      Window container;
+      Window desk;
+   } win;
+   struct {
+      Pixmap pmap;
+      Evas desk;
+   } evas;
+   int x, y;
+   struct {
+      int w, h;
+   } real, virt;
+   Evas_List windows;
+   int changed;
+};
+
+struct _E_Rect
+{
+   int x, y, w, h;
+   int v1, v2, v3, v4;
+};
+
+void e_action_add_proto(char *action,
+                       void (*func_start) (void *o, E_Action *a, void *data, int x, int y, int rx, int ry),
+                       void (*func_stop)  (void *o, E_Action *a, void *data, int x, int y, int rx, int ry),
+                       void (*func_go)    (void *o, E_Action *a, void *data, int x, int y, int rx, int ry, int dx, int dy));
+void e_actions_init(void);
+void e_action_start(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o, void *data, int x, int y, int rx, int ry);
+void e_action_stop(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o, void *data, int x, int y, int rx, int ry);
+void e_action_go(char *action, int act, int button, char *key, Ev_Key_Modifiers mods, void *o, void *data, int x, int y, int rx, int ry, int dx, int dy);
+void e_action_stop_by_object(void *o, void *data, int x, int y, int rx, int ry);
+
+void e_border_apply_border(E_Border *b);
+E_Border * e_border_new(void);
+E_Border * e_border_adopt(Window win, int use_client_pos);
+void e_border_free(E_Border *b);
+void e_border_remove_mouse_grabs(E_Border *b);
+void e_border_attach_mouse_grabs(E_Border *b);
+void e_border_remove_all_mouse_grabs(void);
+void e_border_attach_all_mouse_grabs(void);
+void e_border_redo_grabs(void);
+E_Border * e_border_find_by_window(Window win);
+void e_border_set_bits(E_Border *b, char *file);
+void e_border_set_color_class(E_Border *b, char *class, int rr, int gg, int bb, int aa);
+void e_border_adjust_limits(E_Border *b);
+void e_border_update(E_Border *b);
+void e_border_set_layer(E_Border *b, int layer);
+void e_border_raise(E_Border *b);
+void e_border_lower(E_Border *b);
+void e_border_raise_above(E_Border *b, E_Border *above);
+void e_border_lower_below(E_Border *b, E_Border *below);
+void e_border_init(void);
+
+void e_icccm_move_resize(Window win, int x, int y, int w, int h);
+void e_icccm_delete(Window win);
+void e_icccm_state_mapped(Window win);
+void e_icccm_state_iconified(Window win);
+void e_icccm_state_withdrawn(Window win);
+void e_icccm_adopt(Window win);
+void e_icccm_release(Window win);
+void e_icccm_get_size_info(Window win, E_Border *b);
+void e_icccm_get_mwm_hints(Window win, E_Border *b);
+void e_icccm_get_layer(Window win, E_Border *b);
+void e_icccm_set_frame_size(Window win, int l, int r, int t, int b);
+void e_icccm_set_desk_area(Window win, int ax, int ay);
+void e_icccm_set_desk_area_size(Window win, int ax, int ay);
+void e_icccm_set_desk(Window win, int d);
+void e_icccm_advertise_e_compat(void);
+void e_icccm_advertise_mwm_compat(void);
+void e_icccm_advertise_gnome_compat(void);
+void e_icccm_advertise_kde_compat(void);
+void e_icccm_advertise_net_compat(void);
+
+void e_desktops_init(void);    
+void e_desktops_scroll(E_Desktop *desk, int dx, int dy);
+void e_desktops_free(E_Desktop *desk);
+void e_desktops_init_file_display(E_Desktop *desk);
+E_Desktop * e_desktops_new(void);
+void e_desktops_add_border(E_Desktop *d, E_Border *b);
+void e_desktops_del_border(E_Desktop *d, E_Border *b);
+void e_desktops_delete(E_Desktop *d);
+void e_desktops_show(E_Desktop *d);
+void e_desktops_hide(E_Desktop *d);
+int e_desktops_get_num(void);
+E_Desktop * e_desktops_get(int d);
+int e_desktops_get_current(void);
+void e_desktops_update(E_Desktop *desk);
+
+void e_resist_border(E_Border *b);
+    
+time_t e_file_modified_time(char *file);
+    
diff --git a/src/icccm.c b/src/icccm.c
new file mode 100644 (file)
index 0000000..e81f449
--- /dev/null
@@ -0,0 +1,403 @@
+#include "e.h"
+
+/* Motif window hints */
+#define MWM_HINTS_FUNCTIONS           (1L << 0)
+#define MWM_HINTS_DECORATIONS         (1L << 1)
+#define MWM_HINTS_INPUT_MODE          (1L << 2)
+#define MWM_HINTS_STATUS              (1L << 3)
+
+/* bit definitions for MwmHints.functions */
+#define MWM_FUNC_ALL            (1L << 0)
+#define MWM_FUNC_RESIZE         (1L << 1)
+#define MWM_FUNC_MOVE           (1L << 2)
+#define MWM_FUNC_MINIMIZE       (1L << 3)
+#define MWM_FUNC_MAXIMIZE       (1L << 4)
+#define MWM_FUNC_CLOSE          (1L << 5)
+
+/* bit definitions for MwmHints.decorations */
+#define MWM_DECOR_ALL                 (1L << 0)
+#define MWM_DECOR_BORDER              (1L << 1)
+#define MWM_DECOR_RESIZEH             (1L << 2)
+#define MWM_DECOR_TITLE               (1L << 3)
+#define MWM_DECOR_MENU                (1L << 4)
+#define MWM_DECOR_MINIMIZE            (1L << 5)
+#define MWM_DECOR_MAXIMIZE            (1L << 6)
+
+/* bit definitions for MwmHints.inputMode */
+#define MWM_INPUT_MODELESS                  0
+#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
+#define MWM_INPUT_SYSTEM_MODAL              2
+#define MWM_INPUT_FULL_APPLICATION_MODAL    3
+
+#define PROP_MWM_HINTS_ELEMENTS             5
+
+/* Motif window hints */
+typedef struct _mwmhints
+{
+   int flags;
+   int functions;
+   int decorations;
+   int inputMode;
+   int status;
+}
+MWMHints;
+
+void
+e_icccm_move_resize(Window win, int x, int y, int w, int h)
+{
+   e_window_send_event_move_resize(win, x, y, w, h);
+}
+
+void
+e_icccm_delete(Window win)
+{
+   static Atom a_wm_delete_window = 0;
+   static Atom a_wm_protocols = 0;
+   int *props;
+   int size;
+   int del_win = 0;
+   
+   E_ATOM(a_wm_delete_window, "WM_DELETE_WINDOW");
+   E_ATOM(a_wm_protocols, "WM_PROTOCOLS");
+   
+   props = e_window_property_get(win, a_wm_protocols, XA_ATOM, &size);
+   if (props)
+     {
+       int i, num;
+       
+       num = size / sizeof(int);
+       for (i = 0; i < num; i++)
+         {
+            if (props[i] == (int)a_wm_delete_window) del_win = 1;
+         }
+       FREE(props);
+     }
+   if (del_win)
+     {
+       unsigned int data[5];
+       
+       data[0] = a_wm_delete_window;
+       data[1] = CurrentTime;
+       e_window_send_client_message(win, a_wm_protocols, 32, data);
+     }
+   else
+     {
+       e_window_kill_client(win);
+     }
+}
+
+void
+e_icccm_state_mapped(Window win)
+{
+   static Atom a_wm_state = 0;
+   unsigned int data[2];
+   
+   E_ATOM(a_wm_state, "WM_STATE");
+   data[0] = NormalState;
+   data[1] = 0;
+   e_window_property_set(win, a_wm_state, a_wm_state, 32, data, 2);
+}
+
+void
+e_icccm_state_iconified(Window win)
+{
+   static Atom a_wm_state = 0;
+   unsigned int data[2];
+   
+   E_ATOM(a_wm_state, "WM_STATE");
+   data[0] = IconicState;
+   data[1] = 0;
+   e_window_property_set(win, a_wm_state, a_wm_state, 32, data, 2);
+}
+
+void
+e_icccm_state_withdrawn(Window win)
+{
+   static Atom a_wm_state = 0;
+   unsigned int data[2];
+   
+   E_ATOM(a_wm_state, "WM_STATE");
+   data[0] = WithdrawnState;
+   data[1] = 0;
+   e_window_property_set(win, a_wm_state, a_wm_state, 32, data, 2);
+}
+
+void
+e_icccm_adopt(Window win)
+{
+   e_window_add_to_save_set(win);
+}
+
+void
+e_icccm_release(Window win)
+{
+   e_window_del_from_save_set(win);
+}
+
+void
+e_icccm_get_size_info(Window win, E_Border *b)
+{
+   int x, y, w, h;
+   int base_w, base_h, min_w, min_h, max_w, max_h, grav, step_w, step_h;
+   double aspect_min, aspect_max;
+   int mask;
+   XSizeHints hint;
+   
+   x = 0; y = 0; w = 0; h = 0;
+   e_window_get_geometry(win, &x, &y, &w, &h);
+   
+   printf("window at %i %i\n", x, y);
+   
+   grav = NorthWestGravity;
+   mask = 0;
+   min_w = 0;
+   min_h = 0;
+   max_w = 65535;
+   max_h = 65535;
+   aspect_min = 0.0;
+   aspect_max = 999999.0;
+   step_w = 1;
+   step_h = 1;
+   base_w = 0;
+   base_h = 0;
+   if (e_window_get_wm_size_hints(win, &hint, &mask))
+     {
+       if (hint.flags & PWinGravity) grav = hint.win_gravity;
+       if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
+         {
+         }
+       else
+         {
+            x = rand()%640;
+            y = rand()%480;         
+         }
+       if (hint.flags & PMinSize)
+         {
+            min_w = hint.min_width;
+            min_h = hint.min_height;
+         }
+        if (hint.flags & PMaxSize)
+         {
+            max_w = hint.max_width;
+            max_h = hint.max_height;
+            if (max_w < min_w) max_w = min_w;
+            if (max_h < min_h) max_h = min_h;
+         }
+        if (hint.flags & PResizeInc)
+         {
+            step_w = hint.width_inc;
+            step_h = hint.height_inc;
+            if (step_w < 1) step_w = 1;
+            if (step_h < 1) step_h = 1;
+         }
+        if (hint.flags & PBaseSize)
+         {
+            base_w = hint.base_width;
+            base_h = hint.base_height;
+            if (base_w > max_w) max_w = base_w;
+            if (base_h > max_h) max_h = base_h;
+         }
+       else
+         {
+            base_w = min_w;
+            base_h = min_h;
+         }
+        if (hint.flags & PAspect)
+         {
+            if (hint.min_aspect.y > 0)
+              aspect_min = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y);
+            if (hint.max_aspect.y > 0)
+              aspect_max = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y);
+         }
+     }
+   else
+     {
+       /* get x,y location of client */
+       x = rand()%640;
+       y = rand()%480;
+     }
+     {
+       int pl, pr, pt, pb;
+       
+       pl = pr = pt = pb = 0;
+       if (b->bits.l) ebits_get_insets(b->bits.l, &pl, &pr, &pt, &pb);
+       b->current.requested.x = x - pl;
+       b->current.requested.y = y - pt;
+       b->current.requested.w = w + pl + pr;
+       b->current.requested.h = h + pt + pb;
+       b->client.min.w = min_w;
+       b->client.min.h = min_h;
+       b->client.max.w = max_w;
+       b->client.max.h = max_h;
+       b->client.base.w = base_w;
+       b->client.base.h = base_h;
+       b->client.step.w = step_w;
+       b->client.step.h = step_h;
+       b->client.min.aspect = aspect_min;
+       b->client.max.aspect = aspect_max;
+       b->changed = 1;
+     }
+}
+
+void
+e_icccm_get_mwm_hints(Window win, E_Border *b)
+{
+   static Atom  a_motif_wm_hints = 0;
+   MWMHints    *mwmhints;
+   int          size;
+   
+   E_ATOM(a_motif_wm_hints, "_MOTIF_WM_HINTS");
+   
+   mwmhints = e_window_property_get(win, a_motif_wm_hints, a_motif_wm_hints, &size);
+   if (mwmhints)
+     {
+       int i, num;
+       
+       num = size / sizeof(int);
+       if (num < PROP_MWM_HINTS_ELEMENTS) 
+         {
+            FREE(mwmhints);
+            return;
+         }
+       if (mwmhints->flags & MWM_HINTS_DECORATIONS)
+         {
+            b->client.border = 0;
+            b->client.handles = 0;
+            b->client.titlebar = 0;
+            if (mwmhints->decorations & MWM_DECOR_ALL)
+              {
+                 b->client.border = 1;
+                 b->client.handles = 1;
+                 b->client.titlebar = 1;
+              }
+            if (mwmhints->decorations & MWM_DECOR_BORDER) b->client.border = 1;
+            if (mwmhints->decorations & MWM_DECOR_RESIZEH)  b->client.handles = 1;
+            if (mwmhints->decorations & MWM_DECOR_TITLE) b->client.titlebar = 1;
+         }
+       FREE(mwmhints);
+     }
+}
+
+void
+e_icccm_get_layer(Window win, E_Border *b)
+{
+   static Atom  a_win_layer = 0;
+   int         *props;
+   int          size;
+
+   E_ATOM(a_win_layer, "_WIN_LAYER");
+   
+   props = e_window_property_get(win, a_win_layer, XA_CARDINAL, &size);
+   if (props)
+     {
+       int i, num;
+       
+       num = size / sizeof(int);
+       if (num > 0) b->client.layer = props[0];
+       FREE(props);
+     }
+}
+
+void
+e_icccm_set_frame_size(Window win, int l, int r, int t, int b)
+{
+   static Atom  a_e_frame_size = 0;
+   int props[4];
+
+   E_ATOM(a_e_frame_size, "_E_FRAME_SIZE");
+   props[0] = l;
+   props[1] = r;
+   props[2] = t;
+   props[3] = b;
+   e_window_property_set(win, a_e_frame_size, XA_CARDINAL, 32, props, 4);
+}
+
+void
+e_icccm_set_desk_area(Window win, int ax, int ay)
+{
+   static Atom  a_win_area = 0;
+   int props[2];
+
+   E_ATOM(a_win_area, "_WIN_AREA");
+   props[0] = ax;
+   props[1] = ay;
+   e_window_property_set(win, a_win_area, XA_CARDINAL, 32, props, 2);
+}
+
+void
+e_icccm_set_desk_area_size(Window win, int ax, int ay)
+{
+   static Atom  a_win_area_count = 0;
+   int props[2];
+
+   E_ATOM(a_win_area_count, "_WIN_AREA_COUNT");
+   props[0] = ax;
+   props[1] = ay;
+   e_window_property_set(win, a_win_area_count, XA_CARDINAL, 32, props, 2);
+}
+
+void
+e_icccm_set_desk(Window win, int d)
+{
+   static Atom  a_win_workspace = 0;
+   int props[2];
+
+   E_ATOM(a_win_workspace, "_WIN_WORKSPACE");
+   props[0] = d;
+   e_window_property_set(win, a_win_workspace, XA_CARDINAL, 32, props, 1);
+}
+
+void
+e_icccm_advertise_e_compat(void)
+{
+}
+
+void
+e_icccm_advertise_mwm_compat(void)
+{
+   static Atom  a_motif_wm_info = 0;
+   int props[2];
+   
+   E_ATOM(a_motif_wm_info, "_MOTIF_WM_INFO");
+   props[0] = 2;
+   props[0] = e_window_root();
+   e_window_property_set(0, a_motif_wm_info, a_motif_wm_info, 32, props, 2);   
+}
+
+void
+e_icccm_advertise_gnome_compat(void)
+{
+   static Atom  a_win_supporting_wm_check = 0;
+   static Atom  a_win_protocols = 0;
+   static Atom  a_win_wm_name = 0;
+   static Atom  a_win_wm_version = 0;
+   static Atom  a_win_layer = 0;
+   int props[32];
+   Window win;
+
+   E_ATOM(a_win_protocols, "_WIN_PROTOCOLS");
+   E_ATOM(a_win_protocols, "_WIN_LAYER");
+   props[0] = a_win_protocols;
+   e_window_property_set(0, a_win_protocols, XA_ATOM, 32, props, 1);
+
+   E_ATOM(a_win_wm_name, "_WIN_WM_NAME");
+   e_window_property_set(win, a_win_wm_name, XA_STRING, 8, "Enlightenment", strlen("Enlightenment"));
+   E_ATOM(a_win_wm_version, "_WIN_WM_VERSION");
+   e_window_property_set(win, a_win_wm_version, XA_STRING, 8, "0.17.0", strlen("0.17.0"));
+   
+   E_ATOM(a_win_supporting_wm_check, "_WIN_SUPPORTING_WM_CHECK");
+   win = e_window_override_new(0, 0, 0, 7, 7);
+   props[0] = win;
+   e_window_property_set(win, a_win_supporting_wm_check, XA_CARDINAL, 32, props, 1); 
+   e_window_property_set(0, a_win_supporting_wm_check, XA_CARDINAL, 32, props, 1); 
+}
+
+void
+e_icccm_advertise_kde_compat(void)
+{
+}
+
+void
+e_icccm_advertise_net_compat(void)
+{
+}
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..da5c62b
--- /dev/null
@@ -0,0 +1,55 @@
+#include "e.h"
+
+#ifdef E_PROF
+Evas_List __e_profiles = NULL;
+#endif
+
+static void cb_exit(void);
+static void cb_exit(void)
+{
+   printf("cb_exit\n");
+   E_PROF_DUMP;
+}
+
+static void ch_col(int val, void *data);
+static void ch_col(int val, void *data)
+{
+   E_Desktop *desk;
+   double v;
+   
+   v = (double)val / 10;
+   desk = e_desktops_get(e_desktops_get_current());
+   e_desktops_scroll(desk, (int)(8 * sin(v)), (int)(8 * cos(v)));
+   e_add_event_timer("time", 0.02, ch_col, val + 1, NULL);
+}
+
+void setup(void);
+void
+setup(void)
+{
+   e_grab();
+   e_window_set_events(0, XEV_CHILD_REDIRECT | XEV_PROPERTY | XEV_COLORMAP);
+   e_border_adopt_children(0);
+   e_ungrab();
+/*   e_add_event_timer("timer", 0.02, ch_col, 0, NULL);*/
+}
+
+int
+main(int argc, char **argv)
+{
+   atexit(cb_exit);
+   e_display_init(NULL);
+   e_ev_signal_init();
+   e_event_filter_init();
+   e_ev_x_init();
+
+   e_desktops_init();
+   e_border_init();
+   e_actions_init();
+   
+   setup();
+   
+   e_event_loop();
+
+   return 0;
+}
diff --git a/src/resist.c b/src/resist.c
new file mode 100644 (file)
index 0000000..c4d4016
--- /dev/null
@@ -0,0 +1,129 @@
+#include "e.h"
+
+void
+e_resist_border(E_Border *b)
+{
+   int resist = 1;
+   int desk_resist = 32;
+   int win_resist = 12;
+   int ok;
+   int dx, dy, d;
+   int resist_x = 0, resist_y = 0;
+   char *settings_db = "./settings.db";
+   Evas_List l, rects = NULL;
+   E_Rect *r;
+
+   E_DB_INT_GET(settings_db, "/move/resist", resist, ok);
+   if (!ok) resist = 1;
+   if (!resist)
+     {
+       b->current.x = b->current.requested.x;
+       b->current.y = b->current.requested.y;
+       return;
+     }
+   E_DB_INT_GET(settings_db, "/move/resist/desk", desk_resist, ok);
+   if (!ok) desk_resist = 32;
+   E_DB_INT_GET(settings_db, "/move/resist/win", win_resist, ok);
+   if (!ok) win_resist = 12;
+   if (!b->desk) return;
+   dx = b->current.requested.x - b->previous.requested.x;
+   dy = b->current.requested.y - b->previous.requested.y;
+   /* edges of screen */
+#define OBSTACLE(_x, _y, _w, _h, _resist) \
+{ \
+r = NEW(E_Rect, 1); \
+r->x = _x; r->y = _y; r->w = _w; r->h = _h; r->v1 = _resist; \
+rects = evas_list_append(rects, r); \
+}
+   OBSTACLE(-1000000, -1000000, 2000000 + b->desk->real.w, 1000000, desk_resist); 
+   OBSTACLE(-1000000, -1000000, 1000000, 2000000 + b->desk->real.h, desk_resist); 
+   OBSTACLE(-1000000, b->desk->real.h, 2000000 + b->desk->real.w, 1000000, desk_resist); 
+   OBSTACLE(b->desk->real.w, -1000000, 1000000, 2000000 + b->desk->real.h, desk_resist); 
+  
+   for (l = b->desk->windows; l; l = l->next)
+     {
+       E_Border *bd;
+       
+       bd = l->data;
+       if (bd != b)
+         {
+            r = NEW(struct _E_Rect, 1);
+            r->x = bd->current.x;
+            r->y = bd->current.y;
+            r->w = bd->current.w;
+            r->h = bd->current.h;
+            r->v1 = win_resist;
+            rects = evas_list_append(rects, r);
+         }
+     }
+   for (l = rects; l; l = l->next)
+     {
+       r = l->data;
+       if (SPANS_COMMON(r->y, r->h, b->current.requested.y, b->current.h))
+         {
+            if (dx > 0)
+              {
+                 /* moving right - check left edge of windows against right */
+                 d = r->x - (b->current.requested.x + b->current.w);
+                 if ((d < 0) && (d >= - r->v1)) 
+                   {
+                      if (resist_x > d) resist_x = d;
+                   }
+              }
+            else if (dx < 0)
+              {
+                 /* moving left - check right edge of windows against left */
+                 d = b->current.requested.x - (r->x + r->w);
+                 if ((d < 0) && (d >= - r->v1))
+                   {
+                      if (resist_x > d) resist_x = -d;
+                   }
+              }
+         }
+       if (SPANS_COMMON(r->x, r->w, b->current.requested.x, b->current.w))
+         {
+            if (dy > 0)
+              {
+                 /* moving down - check top edge of windows against bottom */
+                 d = r->y - (b->current.requested.y + b->current.h);
+                 if ((d < 0) && (d >=2 - r->v1))
+                   {
+                      if (resist_y > d) resist_y = d;
+                   }
+              }
+            else if (dy < 0)
+              {
+                 /* moving up - check bottom edge of windows against top */
+                 d = b->current.requested.y - (r->y + r->h);
+                 if ((d < 0) && (d >= - r->v1))
+                   {
+                      if (resist_y > d) resist_y = -d;
+                   }
+              }
+         }
+     }
+   if (rects)
+     {
+       for (l = rects; l; l = l->next)
+         {
+            FREE(l->data);
+         }          
+       evas_list_free(rects);
+     }
+   if (dx != 0) 
+     {
+       if (((b->previous.requested.dx < 0) && (b->current.requested.dx > 0)) ||
+           ((b->previous.requested.dx > 0) && (b->current.requested.dx < 0)))
+         b->current.requested.x = b->current.x;
+       else
+         b->current.x = b->current.requested.x + resist_x;
+     }
+   if (dy != 0) 
+     {
+       if (((b->previous.requested.dy < 0) && (b->current.requested.dy > 0)) ||
+           ((b->previous.requested.dy > 0) && (b->current.requested.dy < 0)))
+         b->current.requested.y = b->current.y;
+       else
+         b->current.y = b->current.requested.y + resist_y;
+     }
+}
diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..74aa768
--- /dev/null
@@ -0,0 +1,10 @@
+#include "e.h"
+
+time_t
+e_file_modified_time(char *file)
+{
+   struct stat         st;
+   
+   if (stat(file, &st) < 0) return 0;
+   return st.st_mtime;
+}