aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Haitzler <raster@rasterman.com>2000-12-08 22:54:42 +0000
committerCarsten Haitzler <raster@rasterman.com>2000-12-08 22:54:42 +0000
commitdfe5d7091ac85950555b83eaa1eea77967192e5d (patch)
tree5d1317616b77690cb3d3acdab6cd57b77644d7ef
downloadenlightenment-dfe5d7091ac85950555b83eaa1eea77967192e5d.tar.gz
e 0.17 ...... :)
SVN revision: 3961
-rw-r--r--AUTHORS1
-rw-r--r--COPYING20
-rw-r--r--ChangeLog0
-rw-r--r--INSTALL14
-rw-r--r--Makefile.am31
-rw-r--r--NEWS0
-rw-r--r--README3
-rwxr-xr-xautogen.sh148
-rw-r--r--config.h.in133
-rw-r--r--configure.in74
-rw-r--r--e.spec66
-rw-r--r--po/ChangeLog0
-rw-r--r--po/POTFILES.in3
-rw-r--r--po/e.pot15
-rw-r--r--src/Makefile.am20
-rw-r--r--src/actions.c748
-rw-r--r--src/border.c1803
-rw-r--r--src/desktops.c508
-rw-r--r--src/e.h337
-rw-r--r--src/icccm.c403
-rw-r--r--src/main.c55
-rw-r--r--src/resist.c129
-rw-r--r--src/util.c10
23 files changed, 4521 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 000000000..186ceed7b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+The Rasterman <raster@rasterman.com>
diff --git a/COPYING b/COPYING
new file mode 100644
index 000000000..dee3047c3
--- /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
index 000000000..e69de29bb
--- /dev/null
+++ b/ChangeLog
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 000000000..e507f3c70
--- /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
index 000000000..c6b6c2afe
--- /dev/null
+++ b/Makefile.am
@@ -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
index 000000000..e69de29bb
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 000000000..32dbee666
--- /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
index 000000000..293b7972e
--- /dev/null
+++ b/autogen.sh
@@ -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
index 000000000..3f449a9c2
--- /dev/null
+++ b/config.h.in
@@ -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
index 000000000..b6a7ac141
--- /dev/null
+++ b/configure.in
@@ -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
index 000000000..7b168f1f6
--- /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
index 000000000..e69de29bb
--- /dev/null
+++ b/po/ChangeLog
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 000000000..a0b3c552e
--- /dev/null
+++ b/po/POTFILES.in
@@ -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
index 000000000..a3edd9568
--- /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
index 000000000..eb7caf2ee
--- /dev/null
+++ b/src/Makefile.am
@@ -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
index 000000000..1679c2f77
--- /dev/null
+++ b/src/actions.c
@@ -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
index 000000000..dcb645e77
--- /dev/null
+++ b/src/border.c
@@ -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
index 000000000..74dc908a0
--- /dev/null
+++ b/src/desktops.c
@@ -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
index 000000000..41565f746
--- /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
index 000000000..e81f4490a
--- /dev/null
+++ b/src/icccm.c
@@ -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
index 000000000..da5c62b30
--- /dev/null
+++ b/src/main.c
@@ -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
index 000000000..c4d4016fe
--- /dev/null
+++ b/src/resist.c
@@ -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
index 000000000..74aa7689a
--- /dev/null
+++ b/src/util.c
@@ -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;
+}