From dfe5d7091ac85950555b83eaa1eea77967192e5d Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Fri, 8 Dec 2000 22:54:42 +0000 Subject: [PATCH] e 0.17 ...... :) SVN revision: 3961 --- AUTHORS | 1 + COPYING | 20 + ChangeLog | 0 INSTALL | 14 + Makefile.am | 31 + NEWS | 0 README | 3 + autogen.sh | 148 ++++ config.h.in | 133 ++++ configure.in | 74 ++ e.spec | 66 ++ po/ChangeLog | 0 po/POTFILES.in | 3 + po/e.pot | 15 + src/Makefile.am | 20 + src/actions.c | 748 ++++++++++++++++++++ src/border.c | 1803 +++++++++++++++++++++++++++++++++++++++++++++++ src/desktops.c | 508 +++++++++++++ src/e.h | 337 +++++++++ src/icccm.c | 403 +++++++++++ src/main.c | 55 ++ src/resist.c | 129 ++++ src/util.c | 10 + 23 files changed, 4521 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100755 autogen.sh create mode 100644 config.h.in create mode 100644 configure.in create mode 100644 e.spec create mode 100644 po/ChangeLog create mode 100644 po/POTFILES.in create mode 100644 po/e.pot create mode 100644 src/Makefile.am create mode 100644 src/actions.c create mode 100644 src/border.c create mode 100644 src/desktops.c create mode 100644 src/e.h create mode 100644 src/icccm.c create mode 100644 src/main.c create mode 100644 src/resist.c create mode 100644 src/util.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..186ceed7b --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +The Rasterman 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 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 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 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 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 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 header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the 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 +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 +- Created spec file diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 000000000..e69de29bb 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 , 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 \n" +"Language-Team: LANGUAGE \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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +}