--- /dev/null
+The Rasterman <raster@rasterman.com>
+Tom Gilbert <tom@linuxbrit.co.uk>
+Burra <burra@colorado.edu>
+Chris Ross <chris@darkrock.co.uk>
+Term <term@twistedpath.org>
+Tilman Sauerbeck <tilman@code-monkey.de>
+Ibukun Olumuyiwa <ibukun@computer.org>
+Yuri <da2001@hotmail.ru>
+Nicholas Curran <quasar@bigblue.net.au>
+Howell Tam <pigeon@pigeond.net>
+Nathan Ingersoll <rbdpngn@users.sourceforge.net>
+Andrew Elcock <andy@elcock.org>
+Kim Woelders <kim@woelders.dk>
+Sebastian Dransfeld <sebastid@tango.flipp.net>
+Simon Poole <simon.armlinux@themalago.net>
+Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
+dan sinclair <zero@everburning.com>
+Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
+David 'onefang' Seikel <onefang@gmail.com>
+Hisham 'CodeWarrior' Mardam Bey <hisham@hisham.cc>
+Brian 'rephorm' Mattern <rephorm@rephorm.com>
+Tim Horton <hortont424@gmail.com>
+Arnaud de Turckheim 'quarium' <quarium@gmail.com>
+Matt Barclay <mbarclay@gmail.com>
+Peter Wehrfritz <peter.wehrfritz@web.de>
+Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com>
+Vincent Torri <vincent.torri@gmail.com>
+Lars Munch <lars@segv.dk>
+Andre Dieb <andre.dieb@gmail.com>
+Mathieu Taillefumier <mathieu.taillefumier@free.fr>
+Rui Miguel Silva Seabra <rms@1407.org>
--- /dev/null
+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.
--- /dev/null
+Plain English Copyright Notice
+
+This file is not intended to be the actual License. The reason this file
+exists is that we here are programmers and engineers. We aren't lawyers. We
+provide licenses that we THINK say the right things, but we have our own
+intentions at heart. This is a plain-english explanation of what those
+intentions are, and if you follow them you will be within the "spirit" of
+the license.
+
+The intent is for us to enjoy writing software that is useful to us (the
+AUTHORS) and allow others to use it freely and also benefit from the work we
+put into making it. We don't want to restrict others using it. They should
+not *HAVE* to make the source code of the applications they write that
+simply link to these libraries (be that statically or dynamically), or for
+them to be limited as to what license they choose to use (be it open, closed
+or anything else). But we would like to know you are using these libraries.
+We simply would like to know that it has been useful to someone. This is why
+we ask for acknowledgement of some sort.
+
+You can do what you want with the source of this software - it doesn't
+matter. We still have it here for ourselves and it is open and free to use
+and download and play with. It can't be taken away. We don't really mind what
+you do with the source to your software. We would simply like to know that
+you are using it - especially if it makes it to a commerical product. If you
+simply e-mail all the AUTHORS (see COPYING and AUTHORS files) telling us, and
+then make sure you include a paragraph or page in the manual for the product
+with the copyright notice and state that you used this software, we will be
+very happy. If you want to contribute back modifications and fixes you may have
+made we will welcome those too with open arms (generally). If you want help
+with changes needed, ports needed or features to be added, arrangements can
+be easily made with some dialogue.
+
+Carsten Haitzler <raster@rasterman.com>
--- /dev/null
+Wed Jun 8 16:56:30 2005 Michael Jennings (mej)
+
+Fix spec file.
+----------------------------------------------------------------------
--- /dev/null
+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 Eet for it to run properly.
--- /dev/null
+## Process this file with automake to produce Makefile.in
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = doc src po
+
+
+MAINTAINERCLEANFILES = \
+ABOUT-NLS \
+Makefile.in \
+aclocal.m4 \
+autom4te.cache \
+config.guess \
+config.h.in \
+config.h.in~ \
+config.rpath \
+config.sub \
+configure \
+depcomp \
+install-sh \
+ltmain.sh \
+missing \
+mkinstalldirs \
+$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.gz \
+$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.bz2 \
+$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-doc.tar.bz2 \
+m4/libtool.m4 \
+m4/lt~obsolete.m4 \
+m4/ltoptions.m4 \
+m4/ltsugar.m4 \
+m4/ltversion.m4 \
+m4/codeset.m4 \
+m4/gettext.m4 \
+m4/glibc21.m4 \
+m4/iconv.m4 \
+m4/intdiv0.m4 \
+m4/inttypes_h.m4 \
+m4/inttypes.m4 \
+m4/inttypes-pri.m4 \
+m4/isc-posix.m4 \
+m4/lcmessage.m4 \
+m4/lib-ld.m4 \
+m4/lib-link.m4 \
+m4/lib-prefix.m4 \
+m4/nls.m4 \
+m4/po.m4 \
+m4/progtest.m4 \
+m4/stdint_h.m4 \
+m4/uintmax_t.m4 \
+m4/ulonglong.m4 \
+po/boldquot.sed \
+po/en@boldquot.header \
+po/en@quot.header \
+po/insert-header.sin \
+po/Makefile.in.in \
+po/Makevars.template \
+po/quot.sed \
+po/remove-potcdate.sin \
+po/Rules-quot
+
+bin_SCRIPTS =
+
+EXTRA_DIST = AUTHORS COPYING COPYING-PLAIN \
+ autogen.sh ecore.supp \
+ ecore.pc.in \
+ ecore-con.pc.in \
+ ecore-config.pc.in \
+ ecore-directfb.pc.in\
+ ecore-evas.pc.in \
+ ecore-fb.pc.in \
+ ecore-file.pc.in \
+ ecore-imf.pc.in \
+ ecore-imf-evas.pc.in \
+ ecore-ipc.pc.in \
+ ecore-x.pc.in \
+ ecore-win32.pc.in \
+ ecore-sdl.pc.in \
+ ecore-cocoa.pc.in \
+ ecore-input.pc.in \
+ ecore-wince.pc.in \
+ ecore.spec.in ecore.spec
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ecore.pc
+
+if BUILD_ECORE_CON
+pkgconfig_DATA += ecore-con.pc
+endif
+
+if BUILD_ECORE_CONFIG
+pkgconfig_DATA += ecore-config.pc
+endif
+
+if BUILD_ECORE_DIRECTFB
+pkgconfig_DATA += ecore-directfb.pc
+endif
+
+if BUILD_ECORE_EVAS
+pkgconfig_DATA += ecore-evas.pc
+endif
+
+if BUILD_ECORE_FB
+pkgconfig_DATA += ecore-fb.pc
+endif
+
+if BUILD_ECORE_FILE
+pkgconfig_DATA += ecore-file.pc
+endif
+
+if BUILD_ECORE_IMF
+pkgconfig_DATA += ecore-imf.pc
+endif
+
+if BUILD_ECORE_IMF_EVAS
+pkgconfig_DATA += ecore-imf-evas.pc
+endif
+
+if BUILD_ECORE_INPUT
+pkgconfig_DATA += ecore-input.pc
+endif
+
+if BUILD_ECORE_INPUT_EVAS
+pkgconfig_DATA += ecore-input-evas.pc
+endif
+
+if BUILD_ECORE_IPC
+pkgconfig_DATA += ecore-ipc.pc
+endif
+
+if BUILD_ECORE_X
+pkgconfig_DATA += ecore-x.pc
+endif
+
+if BUILD_ECORE_WIN32
+pkgconfig_DATA += ecore-win32.pc
+endif
+
+if BUILD_ECORE_WINCE
+pkgconfig_DATA += ecore-wince.pc
+endif
+
+if BUILD_ECORE_SDL
+pkgconfig_DATA += ecore-sdl.pc
+endif
+
+if BUILD_ECORE_COCOA
+pkgconfig_DATA += ecore-cocoa.pc
+endif
+
+.PHONY: doc
+
+# Documentation
+
+doc:
+ @echo "entering doc/"
+ make -C doc doc
+
+# Unit tests
+
+if EFL_ENABLE_TESTS
+
+check-local:
+ @./src/tests/ecore_suite
+
+else
+
+check-local:
+ @echo "reconfigure with --enable-tests"
+
+endif
--- /dev/null
+Ecore @VERSION@
+
+Requirements:
+-------------
+
+Must:
+ libc libm
+
+Recommended:
+ libX11 libXext libXcursor libXprint libXinerama libXrandr libXss libXrender
+ libXcomposite libXfixes libXdamage libXdpms libXtest OpenSSL CURL
+
+Optional:
+ XCB SDL DirectFB
+
+Ecore is a clean and tiny event loop library with many modules to do
+lots of convenient things for a programmer, to save time and effort.
+
+It's small and lean, designed to work on embedded systems all the way
+to large and powerful multi-cpu workstations. It serialises all system
+signals, events etc. into a single event queue, that is easily
+processed without needing to worry about concurrency. A properly
+written, event-driven program using this kind of programming doesn't
+need threads, nor has to worry about concurrency. It turns a program
+into a state machine, and makes it very robust and easy to follow.
+
+Ecore gives you other handy primitives, such as timers to tick over
+for you and call specified functions at particular times so the
+programmer can use this to do things, like animate, or time out on
+connections or tasks that take too long etc.
+
+Idle handlers are provided too, as well as calls on entering an idle
+state (often a very good time to update the state of the program). All
+events that enter the system are passed to specific callback functions
+that the program sets up to handle those events. Handling them is
+simple and other Ecore modules produce more events on the queue,
+coming from other sources such as file descriptors etc.
+
+Ecore also lets you have functions called when file descriptors become
+active for reading or writing, allowing for streamlined, non-blocking
+IO.
+
+------------------------------------------------------------------------------
+COMPILING AND INSTALLING:
+
+ ./configure
+ make
+(as root unless youa re installing in your users directories):
+ make install
+
+------------------------------------------------------------------------------
+BUILDING PACKAGES:
+
+RPM: To build rpm packages:
+
+ sudo rpm -ta @PACKAGE@-@VERSION@.tar.gz
+
+You will find rpm packages in your system /usr/src/redhat/* dirs (note you may
+not need to use sudo or root if you have your own ~/.rpmrc. see rpm documents
+for more details)
+
+DEB: To build deb packages:
+
+ tar zvf @PACKAGE@-@VERSION@.tar.gz
+ cd @PACKAGE@-@VERSION@
+ dpkg-buildpackage -us -uc -rfakeroot
+ cd ..
+ rm -rf @PACKAGE@-@VERSION@
+
+You will find all the debian source, binary etc. packages put in the directory
+where you first untarred the source tarball.
--- /dev/null
+#!/bin/sh
+
+rm -rf autom4te.cache
+rm -f aclocal.m4 ltmain.sh
+
+touch README
+
+echo "Running autopoint..." ; autopoint -f || :
+echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS -I m4 || exit 1
+echo "Running autoheader..." ; autoheader || exit 1
+echo "Running autoconf..." ; autoconf || exit 1
+echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1
+echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1
+
+if [ -z "$NOCONFIGURE" ]; then
+ ./configure "$@"
+fi
--- /dev/null
+# get rid of that stupid cache mechanism
+rm -f config.cache
+
+AC_INIT([ecore], [0.9.9.063], [enlightenment-devel@lists.sourceforge.net])
+release="ver-pre-svn-05"
+AC_PREREQ([2.52])
+AC_CONFIG_SRCDIR([configure.ac])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_ISC_POSIX
+
+AM_INIT_AUTOMAKE([1.6 dist-bzip2])
+AM_CONFIG_HEADER([config.h])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AC_GNU_SOURCE
+
+AC_LIBTOOL_WIN32_DLL
+define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
+AC_PROG_LIBTOOL
+
+VMAJ=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $1);}'`
+VMIN=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $2);}'`
+VMIC=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $3);}'`
+SNAP=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $4);}'`
+version_info=`expr $VMAJ + $VMIN`":$VMIC:$VMIN"
+AC_SUBST(version_info)
+
+AM_GNU_GETTEXT_VERSION([0.12.1])
+AM_GNU_GETTEXT([external])
+
+EFL_CHECK_PATH_MAX
+
+case "$host_os" in
+ mingw32ce* | cegcc*)
+ ;;
+ *)
+ ecore_config_release_info="-release $release"
+ ecore_con_release_info="-release $release"
+ ecore_directfb_release_info="-release $release"
+ ecore_evas_release_info="-release $release"
+ ecore_fb_release_info="-release $release"
+ ecore_file_release_info="-release $release"
+ ecore_imf_evas_release_info="-release $release"
+ ecore_imf_release_info="-release $release"
+ ecore_input_release_info="-release $release"
+ ecore_input_evas_release_info="-release $release"
+ ecore_ipc_release_info="-release $release"
+ ecore_cocoa_release_info="-release $release"
+ ecore_release_info="-release $release"
+ ecore_sdl_release_info="-release $release"
+ ecore_win32_release_info="-release $release"
+ ecore_x_release_info="-release $release"
+ ;;
+esac
+AC_SUBST(ecore_config_release_info)
+AC_SUBST(ecore_con_release_info)
+AC_SUBST(ecore_directfb_release_info)
+AC_SUBST(ecore_evas_release_info)
+AC_SUBST(ecore_fb_release_info)
+AC_SUBST(ecore_file_release_info)
+AC_SUBST(ecore_imf_evas_release_info)
+AC_SUBST(ecore_imf_release_info)
+AC_SUBST(ecore_input_release_info)
+AC_SUBST(ecore_input_evas_release_info)
+AC_SUBST(ecore_ipc_release_info)
+AC_SUBST(ecore_cocoa_release_info)
+AC_SUBST(ecore_release_info)
+AC_SUBST(ecore_sdl_release_info)
+AC_SUBST(ecore_win32_release_info)
+AC_SUBST(ecore_wince_release_info)
+AC_SUBST(ecore_x_release_info)
+
+
+with_max_log_level="<unset>"
+AC_ARG_WITH(internal-maximum-log-level,
+ [AC_HELP_STRING([--with-internal-maximum-log-level=NUMBER],
+ [limit ecore internal log level to the given number, any call to EINA_LOG() with values greater than this will be compiled out, ignoring runtime settings, but saving function calls.])],
+ [
+ if test "x${withval}" != "xno"; then
+ if echo "${withval}" | grep '^[[0-9]]\+$' >/dev/null 2>/dev/null; then
+ AC_MSG_NOTICE([ignoring any EINA_LOG() with level greater than ${withval}])
+ AC_DEFINE_UNQUOTED(EINA_LOG_LEVEL_MAXIMUM, ${withval}, [if set, logging is limited to this amount.])
+ with_max_log_level="${withval}"
+ else
+ AC_MSG_ERROR([--with-internal-maximum-log-level takes a decimal number, got "${withval}" instead.])
+ fi
+ fi
+ ], [:])
+
+
+### Default options with respect to host
+
+# dependencies and options
+want_curl="no"
+want_abstract_sockets="no"
+want_gnutls="no"
+want_openssl="no"
+want_cares="no"
+want_cipher="no"
+want_signature="no"
+want_poll="yes"
+want_inotify="no"
+want_notify_win32="no"
+want_tslib="no"
+want_glib="no"
+
+# core modules
+want_ecore_con="yes"
+want_ecore_ipc="no"
+want_ecore_file="yes"
+want_ecore_config="no"
+want_ecore_imf="no"
+want_ecore_input="yes"
+
+# graphic system modules
+want_evas_simple_x11="no"
+want_ecore_x_xcb="no"
+want_ecore_x="no"
+want_ecore_win32="no"
+want_ecore_cocoa="no"
+want_ecore_sdl="no"
+want_ecore_fb="no"
+want_ecore_directfb="no"
+want_ecore_wince="no"
+
+# ecore_x options (both xlib and xcb)
+want_ecore_x_composite="yes"
+want_ecore_x_damage="yes"
+want_ecore_x_dpms="yes"
+want_ecore_x_randr="yes"
+want_ecore_x_render="yes"
+want_ecore_x_screensaver="yes"
+want_ecore_x_shape="yes"
+want_ecore_x_sync="yes"
+want_ecore_x_xfixes="yes"
+want_ecore_x_xinerama="yes"
+want_ecore_x_xprint="yes"
+want_ecore_x_xtest="yes"
+want_ecore_x_cursor="yes"
+want_ecore_x_input="yes"
+
+# ecore_evas modules
+want_ecore_evas="yes"
+want_ecore_evas_software_buffer="yes"
+want_ecore_evas_software_x11="no"
+want_ecore_evas_xrender_x11="no"
+want_ecore_evas_opengl_x11="no"
+want_ecore_evas_software_16_x11="no"
+want_ecore_evas_software_xcb="no"
+want_ecore_evas_xrender_xcb="no"
+want_ecore_evas_software_gdi="no"
+want_ecore_evas_software_ddraw="no"
+want_ecore_evas_direct3d="no"
+want_ecore_evas_opengl_glew="no"
+want_ecore_evas_software_16_ddraw="no"
+want_ecore_evas_cocoa="no"
+want_ecore_evas_software_sdl="no"
+want_ecore_evas_gl_sdl="no"
+want_ecore_evas_directfb="no"
+want_ecore_evas_fb="no"
+want_ecore_evas_software_16_wince="no"
+
+case "$host_os" in
+ mingw32ce* | cegcc*)
+ want_ecore_con="no"
+ want_ecore_wince="yes"
+ want_ecore_evas_software_16_wince="yes"
+ ;;
+ mingw*)
+ want_notify_win32="yes"
+ want_curl="yes"
+ want_glib="auto"
+ want_ecore_con="no"
+ want_ecore_imf="yes"
+ want_ecore_win32="yes"
+ want_ecore_evas_software_gdi="yes"
+ want_ecore_evas_software_ddraw="yes"
+ want_ecore_evas_direct3d="yes"
+ want_ecore_evas_opengl_glew="yes"
+ want_ecore_evas_software_16_ddraw="auto"
+ want_ecore_evas_software_sdl="yes"
+ want_ecore_evas_gl_sdl="yes"
+ ;;
+ darwin*)
+ want_curl="yes"
+ want_glib="auto"
+ want_gnutls="auto"
+ want_openssl="auto"
+ want_ecore_ipc="yes"
+ want_ecore_imf="yes"
+ want_ecore_cocoa="yes"
+ want_ecore_evas_cocoa="yes"
+ want_ecore_evas_software_sdl="yes"
+ want_ecore_evas_gl_sdl="yes"
+ ;;
+ *)
+ want_curl="yes"
+ want_glib="auto"
+ want_abstract_sockets="yes"
+ want_gnutls="auto"
+ want_openssl="auto"
+ want_cipher="yes"
+ want_signature="yes"
+ want_inotify="yes"
+ want_tslib="yes"
+ want_ecore_ipc="yes"
+ want_ecore_imf="yes"
+ want_ecore_x="yes"
+ want_ecore_evas_software_x11="yes"
+ want_ecore_evas_xrender_x11="yes"
+ want_ecore_evas_opengl_x11="yes"
+ want_ecore_evas_software_16_x11="yes"
+ want_ecore_evas_software_xcb="yes"
+ want_ecore_evas_xrender_xcb="yes"
+ want_ecore_evas_software_sdl="yes"
+ want_ecore_evas_gl_sdl="yes"
+ want_ecore_evas_directfb="yes"
+ want_ecore_evas_fb="yes"
+ ;;
+esac
+
+requirements_ecore=""
+requirements_ecore_con=""
+requirements_ecore_config=""
+requirements_ecore_directfb=""
+requirements_ecore_evas=""
+requirements_ecore_fb=""
+requirements_ecore_file=""
+requirements_ecore_imf=""
+requirements_ecore_imf_evas=""
+requirements_ecore_input=""
+requirements_ecore_input_evas=""
+requirements_ecore_ipc=""
+requirements_ecore_cocoa=""
+requirements_ecore_sdl=""
+requirements_ecore_x=""
+requirements_ecore_win32=""
+requirements_ecore_wince=""
+
+### Additional options to configure
+
+want_glib_integration_always=no
+AC_ARG_ENABLE(glib-integration-always,
+ AC_HELP_STRING([--enable-glib-integration-always], [enable glib integration when ecore_init() is called always]),
+ [want_glib_integration_always=$enableval])
+
+if test "x${want_glib_integration_always}" = "xyes" ; then
+ AC_DEFINE([GLIB_INTEGRATION_ALWAYS], [1], [Always integrate glib if support compiled])
+fi
+
+# abstract sockets (ecore_con.c)
+AC_ARG_ENABLE([abstract-sockets],
+ [AC_HELP_STRING([--disable-abstract-sockets], [disable abstract sockets.])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_abstract_sockets="yes"
+ else
+ want_abstract_sockets="no"
+ fi
+ ],
+ [want_abstract_sockets="yes"])
+
+if test "x${want_abstract_sockets}" = "xyes" ; then
+ AC_DEFINE([HAVE_ABSTRACT_SOCKETS], [1], [Have abstract sockets namespace])
+fi
+
+# Simple X11 build/link
+
+AC_ARG_ENABLE(simple-x11,
+ AC_HELP_STRING([--enable-simple-x11], [enable simple x11 linking]),
+ [want_evas_simple_x11=$enableval])
+
+# XIM
+AC_ARG_ENABLE([xim],
+ [AC_HELP_STRING([--disable-xim], [disable X Input Method.])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_xim="yes"
+ else
+ want_xim="no"
+ fi
+ ],
+ [want_xim="yes"])
+
+if test "x${want_xim}" = "xyes" ; then
+ AC_DEFINE([ENABLE_XIM], [1], [Enable X Input Method])
+fi
+
+# Unit tests
+
+EFL_CHECK_TESTS([enable_tests="yes"], [enable_tests="no"])
+
+
+### Checks for programs
+
+m4_ifdef([AC_PROG_OBJC],
+ [
+ AC_PROG_OBJC
+ _AM_DEPENDENCIES(OBJC)
+ ],
+ [
+ AC_CHECK_TOOL([OBJC], [gcc])
+ AC_SUBST([OBJC])
+ AC_SUBST([OBJCFLAGS])
+ ])
+m4_ifndef([am__fastdepOBJC], [
+ AM_CONDITIONAL([am__fastdepOBJC], [false])
+ AC_SUBST([cocoa_ldflags])
+])
+
+AC_PROG_CXX
+AC_PROG_CC
+
+have_gnu_objc=${ac_cv_objc_compiler_gnu}
+
+# doxygen program for documentation building
+
+EFL_CHECK_DOXYGEN([build_doc="yes"], [build_doc="no"])
+
+# The first call to PKG_CHECK_MODULES is done conditionally,
+# so we should include this here:
+PKG_PROG_PKG_CONFIG
+
+# Check whether pkg-config supports Requires.private
+if $PKG_CONFIG --atleast-pkgconfig-version 0.22; then
+ pkgconfig_requires_private="Requires.private"
+else
+ pkgconfig_requires_private="Requires"
+fi
+AC_SUBST(pkgconfig_requires_private)
+
+
+### Checks for libraries
+
+# Evil library for compilation on Windows
+
+case "$host_os" in
+ mingw* | cegcc*)
+ PKG_CHECK_MODULES([EVIL], [evil])
+ AC_DEFINE(HAVE_EVIL, 1, [Set to 1 if Evil library is installed])
+ requirements_ecore="evil ${requirements_ecore}"
+ requirements_ecore_evas="evil ${requirements_ecore_evas}"
+ requirements_ecore_file="evil ${requirements_ecore_file}"
+ requirements_ecore_imf="evil ${requirements_ecore_imf}"
+ requirements_ecore_imf_evas="evil ${requirements_ecore_imf_evas}"
+ EFL_ECORE_BUILD="-DEFL_ECORE_BUILD"
+ EFL_ECORE_FILE_BUILD="-DEFL_ECORE_FILE_BUILD"
+ EFL_ECORE_EVAS_BUILD="-DEFL_ECORE_EVAS_BUILD"
+ EFL_ECORE_IMF_BUILD="-DEFL_ECORE_IMF_BUILD"
+ EFL_ECORE_INPUT_BUILD="-DEFL_ECORE_INPUT_BUILD"
+ EFL_ECORE_INPUT_EVAS_BUILD="-DEFL_ECORE_INPUT_EVAS_BUILD"
+ ;;
+esac
+
+have_win32=""
+have_wince=""
+case "$host_os" in
+ mingw32ce* | cegcc*)
+ EFL_ECORE_WINCE_BUILD="-DEFL_ECORE_WINCE_BUILD"
+ requirements_ecore_wince="evil ${requirements_ecore_wince}"
+ have_wince="yes"
+ ;;
+ mingw*)
+ EFL_ECORE_WIN32_BUILD="-DEFL_ECORE_WIN32_BUILD"
+ EFL_ECORE_SDL_BUILD="-DEFL_ECORE_SDL_BUILD"
+ requirements_ecore_win32="evil ${requirements_ecore_win32}"
+ requirements_ecore_sdl="evil ${requirements_ecore_sdl}"
+ have_win32="yes"
+ ;;
+esac
+
+AC_SUBST(EFL_ECORE_BUILD)
+AC_SUBST(EFL_ECORE_FILE_BUILD)
+AC_SUBST(EFL_ECORE_EVAS_BUILD)
+AC_SUBST(EFL_ECORE_IMF_BUILD)
+AC_SUBST(EFL_ECORE_INPUT_BUILD)
+AC_SUBST(EFL_ECORE_INPUT_EVAS_BUILD)
+AC_SUBST(EFL_ECORE_WINCE_BUILD)
+AC_SUBST(EFL_ECORE_WIN32_BUILD)
+AC_SUBST(EFL_ECORE_SDL_BUILD)
+
+AM_CONDITIONAL(ECORE_HAVE_WINCE, test "x${have_wince}" = "xyes")
+AM_CONDITIONAL(ECORE_HAVE_WIN32, test "x${have_win32}" = "xyes")
+
+WIN32_LIBS=""
+case "$host_os" in
+ mingw32ce* | cegcc*)
+ WIN32_LIBS="-lws2"
+ dlopen_libs="-ldl"
+ ;;
+ mingw*)
+ WIN32_LIBS="-lws2_32"
+ dlopen_libs="-ldl"
+ ;;
+ *)
+ AC_CHECK_LIB(dl, dlopen, dlopen_libs=-ldl)
+ ;;
+esac
+AC_SUBST(WIN32_LIBS)
+AC_SUBST(dlopen_libs)
+
+# Eina library
+
+PKG_CHECK_MODULES(EINA, [eina-0])
+#FIXME check all the requirements when the eina move will be finished
+requirements_ecore="eina-0 ${requirements_ecore}"
+requirements_ecore_con="ecore eina-0 ${requirements_ecore_con}"
+requirements_ecore_config="ecore eina-0 ${requirements_ecore_config}"
+requirements_ecore_directfb="ecore eina-0 ${requirements_ecore_directfb}"
+requirements_ecore_evas="ecore eina-0 ${requirements_ecore_evas}"
+requirements_ecore_fb="ecore eina-0 ${requirements_ecore_fb}"
+requirements_ecore_file="ecore eina-0 ${requirements_ecore_file}"
+requirements_ecore_imf="ecore eina-0 ${requirements_ecore_imf}"
+requirements_ecore_imf_evas="ecore eina-0 ${requirements_ecore_imf_evas}"
+requirements_ecore_input="ecore eina-0 ${requirements_ecore_input}"
+requirements_ecore_input_evas="ecore eina-0 ${requirements_ecore_input_evas}"
+requirements_ecore_ipc="ecore eina-0 ${requirements_ecore_ipc}"
+requirements_ecore_cocoa="ecore eina-0 ${requirements_ecore_cocoa}"
+requirements_ecore_sdl="ecore eina-0 ${requirements_ecore_sdl}"
+requirements_ecore_win32="ecore eina-0 ${requirements_ecore_win32}"
+requirements_ecore_wince="ecore eina-0 ${requirements_ecore_wince}"
+requirements_ecore_x="ecore eina-0 ${requirements_ecore_x}"
+
+
+# glib support (main loop integration)
+AC_ARG_ENABLE([glib],
+ [AC_HELP_STRING([--disable-glib], [disable glib support. @<:@default=detect@:>@])],
+ [want_glib=$enableval], [])
+
+if test "x$want_glib" != "xno"; then
+ PKG_CHECK_MODULES([GLIB], [glib-2.0], [have_glib="yes"], [have_glib="no"])
+else
+ have_glib="no"
+fi
+if test "x$want_glib" = "xyes" -a "x$have_glib" = "xno"; then
+ AC_MSG_ERROR([GLib support requested, but no GLib found by pkg-config.])
+elif test "x$have_glib" = "xyes"; then
+ AC_DEFINE(HAVE_GLIB, [1], [Have GLib])
+ requirements_ecore="glib-2.0 ${requirements_ecore}"
+fi
+
+
+# SDL library (ecore_sdl)
+
+have_sdl="no"
+SDL_CONFIG="sdl-config"
+AC_ARG_WITH([sdl-config],
+ [AC_HELP_STRING([--with-sdl-config=PATH], [use sdl-config specified])],
+ [
+ SDL_CONFIG=$withval
+ AC_MSG_NOTICE([using ${SDL_CONFIG} for sdl-config])
+ ])
+
+AC_PATH_PROG([SDL_CONFIG], ["sdl-config"], [""], [$PATH])
+
+if test -n "$SDL_CONFIG" ; then
+ SDL_CFLAGS=`$SDL_CONFIG --cflags`
+ SDL_LIBS=`$SDL_CONFIG --libs`
+ AC_SUBST(SDL_CFLAGS)
+ AC_SUBST(SDL_LIBS)
+ have_sdl="yes"
+else
+ PKG_CHECK_MODULES([SDL], [sdl >= 1.2.0], [have_sdl="yes"], [have_sdl="no"])
+fi
+
+if test "x${have_sdl}" = "xyes" ; then
+ PKG_CHECK_EXISTS([sdl >= 1.3.0],
+ [AC_DEFINE(BUILD_ECORE_EVAS_SDL_130, 1, [Support for SVN SDL])])
+fi
+
+
+# DirectFB library (ecore_directfb)
+
+PKG_CHECK_MODULES([DIRECTFB],
+ [directfb >= 0.9.16],
+ [have_directfb="yes"],
+ [have_directfb="no"])
+
+
+# Eet library (ecore_config)
+
+PKG_CHECK_MODULES([EET],
+ [eet >= 1.0.0],
+ [have_eet="yes"],
+ [have_eet="no"])
+
+
+# Xlib and XCB (ecore_x)
+
+have_x="no"
+have_ecore_x="no"
+have_ecore_x_xlib="no"
+have_ecore_x_xcb="no"
+
+x_dir="";
+x_includes="";
+x_cflags="";
+x_libs="";
+
+ecore_x_libs_private=""
+
+AC_ARG_ENABLE(ecore-x-composite,
+ [AC_HELP_STRING([--disable-ecore-x-composite],
+ [disable the ecore_x support for Xcomposite extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_composite=$enableval])
+
+AC_ARG_ENABLE(ecore-x-damage,
+ [AC_HELP_STRING([--disable-ecore-x-damage],
+ [disable the ecore_x support for Xdamage extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_damage=$enableval])
+
+AC_ARG_ENABLE(ecore-x-dpms,
+ [AC_HELP_STRING([--disable-ecore-x-dpms],
+ [disable the ecore_x support for Xdpms extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_dpms=$enableval])
+
+AC_ARG_ENABLE(ecore-x-randr,
+ [AC_HELP_STRING([--disable-ecore-x-randr],
+ [disable the ecore_x support for Xrandr extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_randr=$enableval])
+
+AC_ARG_ENABLE(ecore-x-render,
+ [AC_HELP_STRING([--disable-ecore-x-render],
+ [disable the ecore_x support for Xrender extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_render=$enableval])
+
+AC_ARG_ENABLE(ecore-x-screensaver,
+ [AC_HELP_STRING([--disable-ecore-x-screensaver],
+ [disable the ecore_x support for Xscreensaver extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_screensaver=$enableval])
+
+AC_ARG_ENABLE(ecore-x-shape,
+ [AC_HELP_STRING([--disable-ecore-x-shape],
+ [disable the ecore_x support for Xshape extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_shape=$enableval])
+
+AC_ARG_ENABLE(ecore-x-sync,
+ [AC_HELP_STRING([--disable-ecore-x-sync],
+ [disable the ecore_x support for Xsync extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_sync=$enableval])
+
+AC_ARG_ENABLE(ecore-x-xfixes,
+ [AC_HELP_STRING([--disable-ecore-x-xfixes],
+ [disable the ecore_x support for Xfixes extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_xfixes=$enableval])
+
+AC_ARG_ENABLE(ecore-x-xinerama,
+ [AC_HELP_STRING([--disable-ecore-x-xinerama],
+ [disable the ecore_x support for Xinerama extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_xinerama=$enableval])
+
+AC_ARG_ENABLE(ecore-x-xprint,
+ [AC_HELP_STRING([--disable-ecore-x-xprint],
+ [disable the ecore_x support for Xprint extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_xprint=$enableval])
+
+AC_ARG_ENABLE(ecore-x-xtest,
+ [AC_HELP_STRING([--disable-ecore-x-xtest],
+ [disable the ecore_x support for Xtest extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_xtest=$enableval])
+
+AC_ARG_ENABLE(ecore-x-cursor,
+ [AC_HELP_STRING([--disable-ecore-x-cursor],
+ [disable the ecore_x support for Xcursor extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_cursor=$enableval])
+
+AC_ARG_ENABLE(ecore-x-input,
+ [AC_HELP_STRING([--disable-ecore-x-input],
+ [disable the ecore_x support for Xinput/Xinput2 extension.
+ @<:@default=detect@:>@])],
+ [want_ecore_x_input=$enableval])
+
+
+AC_ARG_ENABLE(ecore-x-xcb,
+ [AC_HELP_STRING([--enable-ecore-x-xcb],
+ [enable the ecore_x module with XCB backend. @<:@default=disabled@:>@])],
+ [want_ecore_x_xcb=$enableval],
+ [want_ecore_x_xcb="no"])
+
+AC_MSG_CHECKING(whether ecore_x with XCB backend is to be built)
+AC_MSG_RESULT($want_ecore_x_xcb)
+
+if test "x$want_ecore_x_xcb" = "xyes" ; then
+ PKG_CHECK_MODULES(XCB, xcb xcb-icccm xcb-image xcb-keysyms pixman-1,
+ [ have_ecore_x_xcb="yes"
+ requirements_ecore_x="xcb xcb-icccm xcb-image xcb-keysyms pixman-1 ${requirements_ecore_x}" ],
+ [ have_ecore_x_xcb="no" ])
+
+ if test "x$have_ecore_x_xcb" = "xyes" ; then
+ if test "x$want_ecore_x_composite" != "xno"; then
+ PKG_CHECK_MODULES(XCB_COMPOSITE, xcb-composite,
+ [ have_ecore_x_xcb_composite="yes"
+ requirements_ecore_x="xcb-composite ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_COMPOSITE, 1, [Build support for XCB composite]) ],
+ [ have_ecore_x_xcb_composite="no" ])
+ else
+ have_ecore_x_xcb_composite="no"
+ AC_MSG_NOTICE("composite extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_damage" != "xno"; then
+ PKG_CHECK_MODULES(XCB_DAMAGE, xcb-damage,
+ [ have_ecore_x_xcb_damage="yes"
+ requirements_ecore_x="xcb-damage ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_DAMAGE, 1, [Build support for XCB damage]) ],
+ [ have_ecore_x_xcb_damage="no" ])
+ else
+ have_ecore_x_xcb_damage="no"
+ AC_MSG_NOTICE("damage extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_dpms" != "xno"; then
+ PKG_CHECK_MODULES(XCB_DPMS, xcb-dpms,
+ [ have_ecore_x_xcb_dpms="yes"
+ requirements_ecore_x="xcb-dpms ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_DPMS, 1, [Build support for XCB dpms]) ],
+ [ have_ecore_x_xcb_dpms="no" ])
+ else
+ have_ecore_x_xcb_dpms="no"
+ AC_MSG_NOTICE("dpms extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_randr" != "xno"; then
+ PKG_CHECK_MODULES(XCB_RANDR, xcb-randr,
+ [ have_ecore_x_xcb_randr="yes"
+ requirements_ecore_x="xcb-randr ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_RANDR, 1, [Build support for XCB randr]) ],
+ [ have_ecore_x_xcb_randr="no" ])
+ else
+ have_ecore_x_xcb_randr="no"
+ AC_MSG_NOTICE("randr extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_render" != "xno"; then
+ PKG_CHECK_MODULES(XCB_RENDER, xcb-render,
+ [ have_ecore_x_xcb_render="yes"
+ requirements_ecore_x="xcb-render ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_RENDER, 1, [Build support for XCB render]) ],
+ [ have_ecore_x_xcb_render="no" ])
+ else
+ have_ecore_x_xcb_render="no"
+ AC_MSG_NOTICE("render extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_screensaver" != "xno"; then
+ PKG_CHECK_MODULES(XCB_SCREENSAVER, xcb-screensaver,
+ [ have_ecore_x_xcb_screensaver="yes"
+ requirements_ecore_x="xcb-screensaver ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_SCREENSAVER, 1, [Build support for XCB screensaver]) ],
+ [ have_ecore_x_xcb_screensaver="no" ])
+ else
+ have_ecore_x_xcb_screensaver="no"
+ AC_MSG_NOTICE("screensaver extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_shape" != "xno"; then
+ PKG_CHECK_MODULES(XCB_SHAPE, xcb-shape,
+ [ have_ecore_x_xcb_shape="yes"
+ requirements_ecore_x="xcb-shape ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_SHAPE, 1, [Build support for XCB shape]) ],
+ [ have_ecore_x_xcb_shape="no" ])
+ else
+ have_ecore_x_xcb_shape="no"
+ AC_MSG_NOTICE("shape extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_sync" != "xno"; then
+ PKG_CHECK_MODULES(XCB_SYNC, xcb-sync,
+ [ have_ecore_x_xcb_sync="yes"
+ requirements_ecore_x="xcb-sync ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_SYNC, 1, [Build support for XCB sync]) ],
+ [ have_ecore_x_xcb_sync="no" ])
+ else
+ have_ecore_x_xcb_sync="no"
+ AC_MSG_NOTICE("sync extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_xfixes" != "xno"; then
+ PKG_CHECK_MODULES(XCB_XFIXES, xcb-xfixes,
+ [ have_ecore_x_xcb_xfixes="yes"
+ requirements_ecore_x="xcb-xfixes ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_FIXES, 1, [Build support for XCB xfixes]) ],
+ [ have_ecore_x_xcb_xfixes="no" ])
+ else
+ have_ecore_x_xcb_xfixes="no"
+ AC_MSG_NOTICE("xfixes extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_xinerama" != "xno"; then
+ PKG_CHECK_MODULES(XCB_XINERAMA, xcb-xinerama,
+ [ have_ecore_x_xcb_xinerama="yes"
+ requirements_ecore_x="xcb-xinerama ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_XINERAMA, 1, [Build support for XCB xinerama]) ],
+ [ have_ecore_x_xcb_xinerama="no" ])
+ else
+ have_ecore_x_xcb_xinerama="no"
+ AC_MSG_NOTICE("xinerama extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_xprint" != "xno"; then
+ PKG_CHECK_MODULES(XCB_XPRINT, xcb-xprint,
+ [ have_ecore_x_xcb_xprint="yes"
+ requirements_ecore_x="xcb-xprint ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_XPRINT, 1, [Build support for XCB xprint]) ],
+ [ have_ecore_x_xcb_xprint="no" ])
+ else
+ have_ecore_x_xcb_xprint="no"
+ AC_MSG_NOTICE("xprint extension explicitly disabled")
+ fi
+
+ if test "x$want_ecore_x_xtest" != "xno"; then
+ PKG_CHECK_MODULES(XCB_XTEST, xcb-xtest,
+ [ have_ecore_x_xcb_xtest="yes"
+ requirements_ecore_x="xcb-xtest ${requirements_ecore_x}"
+ AC_DEFINE(ECORE_XCB_XTEST, 1, [Build support for XCB xtest]) ],
+ [ have_ecore_x_xcb_xtest="no" ])
+ else
+ have_ecore_x_xcb_xtest="no"
+ AC_MSG_NOTICE("xtest extension explicitly disabled")
+ fi
+
+ AC_DEFINE(HAVE_ECORE_X_XCB, 1, [Defined to 1 if XCB is enabled.])
+
+ x_cflags=$XCB_CFLAGS
+ x_libs=$XCB_LIBS
+ have_x="yes"
+
+ have_ecore_x_xcb_define="-DHAVE_ECORE_X_XCB"
+ AC_SUBST(have_ecore_x_xcb_define)
+ fi
+fi
+
+if ! test "x$have_ecore_x_xcb" = "xyes" ; then
+ AC_PATH_XTRA
+ AC_CHECK_HEADER(X11/X.h,
+ [
+ if test "x$want_evas_simple_x11" = "xyes"; then
+ x_libs="${x_libs} -lX11 -lXext"
+ else
+ x_dir=${x_dir:-/usr/X11R6}
+ x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}}
+ x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext"
+ fi
+ have_ecore_x_xlib="yes"
+ ]
+ )
+
+ if test "x$have_ecore_x_xlib" = "xyes"; then
+ Xcursor_libs=""
+ Xcursor_cflags=""
+ use_Xcursor="no"
+ PCFLAGS=$CFLAGS
+ CFLAGS="$x_cflags $x_includes"
+
+ if test "x$want_ecore_x_cursor" = "xyes"; then
+ AC_CHECK_HEADER(X11/Xcursor/Xcursor.h,
+ [
+ AC_CHECK_LIB(Xcursor, XcursorImageLoadCursor,
+ [
+ AC_DEFINE(ECORE_XCURSOR, 1, [Build support for Xcursor])
+ Xcursor_cflags=""
+ Xcursor_libs="-lXcursor"
+ use_Xcursor="yes"
+ ], [
+ Xcursor_cflags=""
+ Xcursor_libs=""
+ use_Xcursor="no"
+ ], [
+ $x_libs -lXrender
+ ]
+ )
+ ], [
+ Xcursor_cflags=""
+ Xcursor_libs=""
+ use_Xcursor="no"
+ ], [
+ #include <X11/Xlib.h>
+ ]
+ )
+ CFLAGS=$PCFLAGS
+ else
+ Xcursor_cflags=""
+ Xcursor_libs=""
+ use_Xcursor="no"
+ AC_MSG_NOTICE("Xcursor explicitly disabled")
+ fi
+
+ AC_SUBST(Xcursor_cflags)
+ AC_SUBST(Xcursor_libs)
+
+ ECORE_CHECK_X_EXTENSION([Xkb], [XKB.h], [X11], [XkbSetDetectableAutoRepeat], [$want_ecore_x_xkb])
+ ECORE_CHECK_X_EXTENSION([Xcomposite], [Xcomposite.h], [Xcomposite], [XCompositeQueryExtension], [$want_ecore_x_composite])
+ ECORE_CHECK_X_EXTENSION([Xdamage], [Xdamage.h], [Xdamage], [XDamageSubtract], [$want_ecore_x_damage])
+ ECORE_CHECK_X_EXTENSION([Xdpms], [dpms.h], [Xdpms], [DPMSQueryExtension], [$want_ecore_x_dpms])
+ if test "x$use_xdpms" = "xno" ; then
+ ECORE_CHECK_X_EXTENSION([Xdpms], [dpms.h], [Xext], [DPMSQueryExtension], [$want_ecore_x_dpms])
+ fi
+ ECORE_CHECK_X_EXTENSION([Xfixes], [Xfixes.h], [Xfixes], [XFixesExpandRegion], [$want_ecore_x_xfixes])
+ ECORE_CHECK_X_EXTENSION([Xinerama], [Xinerama.h], [Xinerama], [XineramaQueryScreens], [$want_ecore_x_xinerama])
+ ECORE_CHECK_X_EXTENSION([Xprint], [Print.h], [Xp], [XpQueryScreens], [$want_ecore_x_xprint])
+ ECORE_CHECK_X_EXTENSION([Xrandr], [Xrandr.h], [Xrandr], [XRRGetScreenResourcesCurrent], [$want_ecore_x_randr])
+ ECORE_CHECK_X_EXTENSION([Xrender], [Xrender.h], [Xrender], [XRenderFindVisualFormat], [$want_ecore_x_render])
+ ECORE_CHECK_X_EXTENSION([Xtest], [XTest.h], [Xtst], [XTestFakeKeyEvent], [$want_ecore_x_xtest])
+ ECORE_CHECK_X_EXTENSION([Xss], [scrnsaver.h], [Xss], [XScreenSaverSelectInput], [$want_ecore_x_screensaver])
+ ECORE_CHECK_X_EXTENSION([Xi2], [XInput2.h], [Xi], [XIQueryDevice], [$want_ecore_x_input])
+
+ ecore_x_libs_private="${Xcursor_libs} ${XKB_LIBS} ${XCOMPOSITE_LIBS} ${XDAMAGE_LIBS} ${XDPMS_LIBS} ${XFIXES_LIBS} ${XINERAMA_LIBS} ${XPRINT_LIBS} ${XRANDR_LIBS} ${XRENDER_LIBS} ${XTEST_LIBS} ${XSS_LIBS} ${XI2_LIBS}"
+
+ AC_DEFINE(HAVE_ECORE_X_XLIB, 1, [Defined to 1 if Xlib is enabled.])
+ have_x="yes"
+
+ have_ecore_x_xlib="yes"
+ fi
+fi
+
+AC_SUBST(x_cflags)
+AC_SUBST(x_includes)
+AC_SUBST(x_libs)
+AC_SUBST(ecore_x_libs_private)
+
+AM_CONDITIONAL(BUILD_ECORE_X_XLIB, test $have_ecore_x_xlib = yes)
+AM_CONDITIONAL(BUILD_ECORE_X_XCB, test $have_ecore_x_xcb = yes)
+
+
+# Evas library (ecore_config, ecore_input_evas, ecore_imf_evas and ecore_evas)
+
+PKG_CHECK_MODULES([EVAS], [evas >= 0.9.9],
+ [have_evas="yes"],
+ [have_evas="no"])
+
+
+### Checks for header files
+
+AC_HEADER_SYS_WAIT
+
+have_addrinfo="no"
+case "$host_os" in
+ mingw* | cegcc*)
+ AC_DEFINE(HAVE_DLFCN_H, 1, [Define to 1 if you have the <dlfcn.h> header file.])
+ AC_DEFINE(HAVE_SYS_MMAN_H, 1, [Define to 1 if you have the <sys/mman.h> header file.])
+ AC_DEFINE(HAVE_SYS_TIME_H, 1, [Define to 1 if you have the <sys/time.h> header file.])
+ have_addrinfo="yes"
+ ;;
+ *)
+ AC_CHECK_HEADERS([dlfcn.h features.h langinfo.h locale.h sys/time.h sys/mman.h signal.h sys/resource.h])
+ ;;
+esac
+
+# ecore_con
+
+AC_CHECK_HEADERS([arpa/inet.h arpa/nameser.h netinet/tcp.h netinet/in.h sys/socket.h sys/un.h ws2tcpip.h netdb.h])
+
+if test "x${ac_cv_header_netdb_h}" = "xyes" ; then
+ have_addrinfo="yes"
+fi
+
+# Framebuffer (ecore_fb)
+have_fb="no"
+AC_CHECK_HEADER([linux/fb.h],
+ [AC_CHECK_HEADER([linux/input.h], [have_fb="yes"])])
+
+# Cocoa header files (ecore_cocoa)
+
+cocoa_ldflags="";
+have_cocoa="no"
+m4_ifdef([AC_PROG_OBJC], [
+ if test "x${have_gnu_objc}" = "xyes" ; then
+ AC_LANG_PUSH([Objective C])
+ AC_CHECK_HEADER([Cocoa/Cocoa.h],
+ [
+ have_cocoa="yes"
+ cocoa_ldflags="-framework Cocoa"
+ ])
+ AC_LANG_POP([Objective C])
+ fi
+])
+AC_SUBST(cocoa_ldflags)
+
+# basic pthread support
+
+EFL_CHECK_PTHREAD([no], [have_pthread="yes"], [have_pthread="no"])
+
+### Checks for types
+AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(long, 4)
+
+
+### Checks for structures
+
+
+### Checks for compiler characteristics
+AM_PROG_CC_STDC
+AC_C_CONST
+AC_C_BIGENDIAN
+AC_HEADER_STDC
+AC_C___ATTRIBUTE__
+
+WIN32_CPPFLAGS=""
+WIN32_CFLAGS=""
+case "$host_os" in
+ mingw32ce*)
+ WIN32_CPPFLAGS="-D_WIN32_WCE=0x0420"
+ ;;
+ cegcc*)
+ WIN32_CPPFLAGS="-D_WIN32_WCE=0x0420"
+ WIN32_CFLAGS="-mwin32"
+ ;;
+ mingw*)
+ WIN32_CPPFLAGS="-D_WIN32_WINNT=0x0501"
+ ;;
+esac
+AC_SUBST(WIN32_CPPFLAGS)
+AC_SUBST(WIN32_CFLAGS)
+
+
+### Checks for linker characteristics
+
+# use --enable-auto-import on Windows
+
+lt_enable_auto_import=""
+case "$host_os" in
+ mingw* | cegcc*)
+ lt_enable_auto_import="-Wl,--enable-auto-import"
+ ;;
+esac
+AC_SUBST(lt_enable_auto_import)
+
+### Checks for library functions
+AC_FUNC_ALLOCA
+AC_CHECK_FUNCS(gettimeofday strlcpy)
+
+have_atfile_source=auto
+AC_ARG_ENABLE(atfile-source,
+ AC_HELP_STRING([--disable-atfile-source],
+ [disable use of atfile source functions as openat and mkdirat @<:@default=detect@:>@]),
+ [have_atfile_source=$enableval], [have_atfile_source=auto])
+
+if test "x$have_atfile_source" != "xno"; then
+ AC_CHECK_FUNCS(mkdirat,
+ [
+ have_atfile_source=yes
+ AC_DEFINE(HAVE_ATFILE_SOURCE, 1, [mkdirat exists])
+ ],
+ [
+ if test "x$have_atfile_source" = "xyes"; then
+ AC_MSG_ERROR([required atfile-source but no mkdirat()])
+ fi
+ have_atfile_source=no
+ ])
+fi
+
+### Checks for optionnal feature
+AC_CHECK_FUNC(mallinfo,
+ [
+ have_mallinfo=yes
+ AC_DEFINE(HAVE_MALLINFO, 1, [Gather memory statistic])
+ ], [
+ have_mallinfo=no
+ ])
+
+### Ecore modules
+
+## Core modules
+
+# ecore_con
+ECORE_CHECK_MODULE([con], [${want_ecore_con}], [Con], [${have_addrinfo}])
+
+have_curl="no"
+have_gnutls="no"
+have_openssl="no"
+have_cares="no"
+if test "x${have_ecore_con}" = "xyes" ; then
+
+ ECORE_CHECK_CURL([${want_curl}],
+ [
+ have_curl="yes"
+ requirements_ecore_con="libcurl ${requirements_ecore_con}"
+ ],
+ [have_curl="no"])
+
+ ECORE_CHECK_GNUTLS([${want_gnutls}],
+ [have_gnutls="yes"],
+ [have_gnutls="no"])
+
+ ECORE_CHECK_OPENSSL([${want_openssl}],
+ [have_openssl="yes"],
+ [have_openssl="no"])
+
+ if test "x${have_gnutls}" = "xyes" ; then
+ requirements_ecore_con="gnutls ${requirements_ecore_con}"
+ # no need to add it to req_ecore_ipc, since they
+ # depends on ecore_con anyway.
+ else
+ if test "x${have_openssl}" = "xyes" ; then
+ requirements_ecore_con="openssl ${requirements_ecore_con}"
+ # no need to add it to req_ecore_ipc, since they
+ # depends on ecore_con anyway.
+ fi
+ fi
+
+ ECORE_CHECK_CARES([${want_cares}],
+ [
+ have_cares="yes"
+ requirements_ecore_con="libcares ${requirements_ecore_con}"
+ ],
+ [have_cares="no"])
+
+fi
+
+AM_CONDITIONAL([HAVE_CARES], [test "x${have_cares}" = "xyes"])
+
+# ecore_ipc
+ECORE_CHECK_MODULE([ipc], [${want_ecore_ipc}], [Ipc], [${have_ecore_con}],
+ [requirements_ecore_ipc="ecore-con ${requirements_ecore_ipc}"])
+
+# ecore_file
+ECORE_CHECK_MODULE([file], [${want_ecore_file}], [File])
+
+have_poll="no"
+have_inotify="no"
+have_notify_win32="no"
+if test "x${have_ecore_file}" = "xyes" ; then
+ ECORE_CHECK_POLL([${want_poll}], [have_poll="yes"], [have_poll="no"])
+ ECORE_CHECK_INOTIFY([${want_inotify}], [have_inotify="yes"], [have_inotify="no"])
+ ECORE_CHECK_NOTIFY_WIN32([${want_notify_win32}], [have_notify_win32="yes"], [have_notify_win32="no"])
+
+ if test "x${have_ecore_con}" = "xyes" ; then
+ requirements_ecore_file="ecore-con ${requirements_ecore_file}"
+ fi
+fi
+
+# ecore_config
+ecore_config_deps="no"
+if test "x${have_eet}" = "xyes" -a "x${have_evas}" -a "x${have_ecore_ipc}" ; then
+ ecore_config_deps="yes"
+fi
+
+ECORE_CHECK_MODULE([config], [${want_ecore_config}], [Config], [${ecore_config_deps}],
+ [requirements_ecore_config="ecore-ipc evas eet ${requirements_ecore_config}"])
+
+# ecore_imf
+
+ECORE_CHECK_MODULE([imf], [${want_ecore_imf}], [Imf])
+
+# ecore_imf_evas
+
+ecore_imf_evas_deps="no"
+if test "x${have_ecore_imf}" = "xyes" -a "x${have_evas}" = "xyes" ; then
+ ecore_imf_evas_deps="yes"
+fi
+
+ECORE_CHECK_MODULE([imf-evas], [${want_ecore_imf}], [Imf_Evas], [${ecore_imf_evas_deps}],
+ [requirements_ecore_imf_evas="ecore-imf evas ${requirements_ecore_imf_evas}"])
+
+# ecore_input{_evas}
+ECORE_CHECK_MODULE([input], [${want_ecore_input}], [Input])
+ECORE_CHECK_MODULE([input-evas], [${want_ecore_input}], [Input_Evas], [${have_evas}],
+ [requirements_ecore_input_evas="ecore-input evas ${requirements_ecore_input}"])
+
+## Graphic systems
+
+# ecore_x{cb}
+
+ecore_x_deps="no"
+if test "x${have_x}" = "xyes" -a \
+ "x${have_ecore_input}" = "xyes" ; then
+ ecore_x_deps="yes"
+fi
+
+ECORE_CHECK_MODULE([x], [${want_ecore_x}], [X], [${ecore_x_deps}],
+ [
+ ecore_x_libs="$ecore_x_libs $x_libs"
+ requirements_ecore_x="ecore-input ${requirements_ecore_x}"
+ ])
+
+# ecore_win32
+
+ECORE_CHECK_MODULE([win32], [${want_ecore_win32}], [Win32], [${have_ecore_input}],
+ [
+ ecore_win32_libs="-lole32 -lgdi32"
+ requirements_ecore_win32="ecore-input ${requirements_ecore_win32}"
+ ])
+AC_SUBST(ecore_win32_libs)
+
+# ecore_cocoa
+
+ecore_cocoa_deps="no"
+if test "x${have_ecore_input}" = "xyes" -a "x${have_cocoa}" = "xyes" ; then
+ ecore_cocoa_deps="yes"
+fi
+
+ECORE_CHECK_MODULE([cocoa], [${want_ecore_cocoa}], [Cocoa], [${ecore_cocoa_deps}],
+ [requirements_ecore_cocoa="ecore-input ${requirements_ecore_cocoa}"])
+
+# ecore_sdl
+
+ecore_sdl_deps="no"
+if test "x${have_sdl}" = "xyes" -a "x${have_ecore_input}" = "xyes" ; then
+ ecore_sdl_deps="yes"
+fi
+
+ECORE_CHECK_MODULE([sdl], [${want_ecore_sdl}], [Sdl], [${ecore_sdl_deps}],
+ [requirements_ecore_sdl="ecore-input ${requirements_ecore_sdl}"])
+
+# ecore_fb
+ECORE_CHECK_MODULE([fb], [${want_ecore_fb}], [FB], [$have_fb])
+
+if test "x${have_ecore_fb}" = "xyes" ; then
+ ECORE_CHECK_TSLIB([${want_tslib}],
+ [
+ have_tslib="yes"
+ requirements_ecore_fb="${_tslib_requirement} ${requirements_ecore_fb}"
+ ],
+ [have_tslib="no"])
+fi
+
+# ecore_directfb
+
+ECORE_CHECK_MODULE([directfb], [${want_ecore_directfb}], [DirectFB], [${have_directfb}],
+ [requirements_ecore_directfb="directfb ${requirements_ecore_directfb}"])
+
+# ecore_wince
+
+ECORE_CHECK_MODULE([wince], [${want_ecore_wince}], [WinCE], [${have_ecore_input}],
+ [requirements_ecore_win32="ecore-input ${requirements_ecore_win32}"])
+
+## Ecore Evas
+
+# ecore_evas
+
+ecore_evas_deps="no"
+if test "x${have_evas}" = "xyes" -a "x${have_ecore_input}" = "xyes" -a "x${have_ecore_input_evas}" = "xyes" ; then
+ ecore_evas_deps="yes"
+fi
+
+ECORE_CHECK_MODULE([evas], [${want_ecore_evas}], [Evas], [${ecore_evas_deps}],
+ [requirements_ecore_evas="ecore-input ecore-input-evas evas ${requirements_ecore_evas}"])
+
+# ecore_evas_buffer
+
+ECORE_EVAS_CHECK_MODULE([software-buffer],
+ [${want_ecore_evas_software_buffer}],
+ [Software Buffer],
+ [yes])
+
+# ecore_evas_x11
+
+# ecore_evas_software_x11
+
+ECORE_EVAS_CHECK_MODULE([software-x11],
+ [${want_ecore_evas_software_x11}],
+ [Software X11],
+ [${have_ecore_x}])
+
+have_ecore_evas_software_xlib=no"
+have_ecore_evas_software_xcb=no"
+if test "x$have_ecore_evas_software_x11" = "xyes" ; then
+ have_ecore_evas_software_xlib=`${PKG_CONFIG} --variable=Xlib evas-software-x11`
+ if test "x${have_ecore_evas_software_xlib}" = "xyes" -a "x${have_ecore_x_xlib}" = "xyes" ; then
+ AC_DEFINE(BUILD_ECORE_EVAS_SOFTWARE_XLIB, 1, [Evas Software Xlib Engine Support])
+ fi
+ have_ecore_evas_software_xcb=`${PKG_CONFIG} --variable=XCB evas-software-x11`
+ if test "x$have_ecore_evas_software_xcb" = "xyes" -a "x${have_ecore_x_xcb}" = "xyes" ; then
+ AC_DEFINE(BUILD_ECORE_EVAS_SOFTWARE_XCB, 1, [Evas Software XCB Engine Support])
+ fi
+fi
+
+# ecore_evas_xrender_x11
+
+ECORE_EVAS_CHECK_MODULE([xrender-x11],
+ [${want_ecore_evas_xrender_x11}],
+ [XRender Xlib],
+ [${have_ecore_x_xlib}])
+
+# ecore_evas_opengl_x11
+
+ECORE_EVAS_CHECK_MODULE([opengl-x11],
+ [${want_ecore_evas_opengl_x11}],
+ [OpenGL Xlib],
+ [${have_ecore_x_xlib}])
+
+# ecore_evas_software_x11 16 bits
+
+ECORE_EVAS_CHECK_MODULE([software-16-x11],
+ [${want_ecore_evas_software_16_x11}],
+ [Software Xlib 16 bits],
+ [${have_ecore_x_xlib}])
+
+# ecore_evas_xrender_xcb
+
+ECORE_EVAS_CHECK_MODULE([xrender-xcb],
+ [${want_ecore_evas_xrender_xcb}],
+ [XRender XCB],
+ [${ecore_evas_xcb_deps}])
+
+if test "x$have_ecore_evas_software_x11" = "xyes" -o \
+ "x$have_ecore_evas_xrender_x11" = "xyes" -o \
+ "x$have_ecore_evas_opengl_x11" = "xyes" -o \
+ "x$have_ecore_evas_software_16_x11" = "xyes" -o \
+ "x$have_ecore_evas_software_xcb" = "xyes" -o \
+ "x$have_ecore_evas_xrender_xcb" = "xyes"; then
+ AC_DEFINE(BUILD_ECORE_EVAS_X11, 1, [Support for X Window Engines in Ecore_Evas])
+ requirements_ecore_evas="ecore-x ${requirements_ecore_evas}"
+fi
+
+# ecore_evas_win32
+
+ECORE_EVAS_CHECK_MODULE([software-gdi],
+ [${want_ecore_evas_software_gdi}],
+ [Software GDI],
+ [${have_ecore_win32}])
+
+ECORE_EVAS_CHECK_MODULE([software-ddraw],
+ [${want_ecore_evas_software_ddraw}],
+ [Software DirectDraw],
+ [${have_ecore_win32}])
+
+ECORE_EVAS_CHECK_MODULE([direct3d],
+ [${want_ecore_evas_direct3d}],
+ [Direct3d],
+ [${have_ecore_win32}])
+
+ECORE_EVAS_CHECK_MODULE([opengl-glew],
+ [${want_ecore_evas_opengl_glew}],
+ [Glew OpenGL],
+ [${have_ecore_win32}])
+
+ECORE_EVAS_CHECK_MODULE([software-16-ddraw],
+ [${want_ecore_evas_software_16_ddraw}],
+ [16 bpp Software DirectDraw],
+ [${have_ecore_win32}])
+
+if test "x${have_ecore_evas_software_gdi}" = "xyes" -o \
+ "x${have_ecore_evas_software_ddraw}" = "xyes" -o \
+ "x${have_ecore_evas_direct3d}" = "xyes" -o \
+ "x${have_ecore_evas_opengl_glew}" = "xyes" -o \
+ "x${have_ecore_evas_software_16_ddraw}" = "xyes" ; then
+ AC_DEFINE(BUILD_ECORE_EVAS_WIN32, 1, [Support for Win32 Engine in Ecore_Evas])
+ requirements_ecore_evas="ecore-win32 ${requirements_ecore_evas}"
+fi
+
+# ecore_evas_cocoa
+
+ECORE_EVAS_CHECK_MODULE([cocoa],
+ [${want_ecore_evas_cocoa}],
+ [Cocoa],
+ [${have_ecore_cocoa}],
+ [requirements_ecore_evas="ecore-cocoa ${requirements_ecore_evas}"])
+
+# ecore_evas_software_sdl
+
+ECORE_EVAS_CHECK_MODULE([software-sdl],
+ [${want_ecore_evas_software_sdl}],
+ [Software SDL],
+ [${have_ecore_sdl}],
+ [requirements_ecore_evas="ecore-sdl ${requirements_ecore_evas}"])
+
+# ecore_evas_gl_sdl
+
+ECORE_EVAS_CHECK_MODULE([opengl-sdl],
+ [${want_ecore_evas_gl_sdl}],
+ [OpenGL SDL],
+ [${have_ecore_sdl}],
+ [requirements_ecore_evas="ecore-sdl ${requirements_ecore_evas}"])
+
+# ecore_evas_directfb
+
+ECORE_EVAS_CHECK_MODULE([directfb],
+ [${want_ecore_evas_directfb}],
+ [DirectFB],
+ [${have_ecore_directfb}],
+ [requirements_ecore_evas="ecore-directfb ${requirements_ecore_evas}"])
+
+# ecore_evas_fb
+
+ECORE_EVAS_CHECK_MODULE([fb],
+ [${want_ecore_evas_fb}],
+ [Linux Framebuffer],
+ [${have_ecore_fb}],
+ [requirements_ecore_evas="ecore-fb ${requirements_ecore_evas}"])
+
+# ecore_evas_wince
+
+ECORE_EVAS_CHECK_MODULE([software-16-wince],
+ [${want_ecore_evas_software_16_wince}],
+ [16 bpp Software Windows CE],
+ [${have_ecore_wince}],
+ [requirements_ecore_evas="ecore-wince ${requirements_ecore_evas}"])
+
+
+
+### requirements
+
+AC_SUBST(requirements_ecore)
+AC_SUBST(requirements_ecore_con)
+AC_SUBST(requirements_ecore_config)
+AC_SUBST(requirements_ecore_directfb)
+AC_SUBST(requirements_ecore_evas)
+AC_SUBST(requirements_ecore_fb)
+AC_SUBST(requirements_ecore_file)
+AC_SUBST(requirements_ecore_imf)
+AC_SUBST(requirements_ecore_imf_evas)
+AC_SUBST(requirements_ecore_input)
+AC_SUBST(requirements_ecore_input_evas)
+AC_SUBST(requirements_ecore_ipc)
+AC_SUBST(requirements_ecore_cocoa)
+AC_SUBST(requirements_ecore_sdl)
+AC_SUBST(requirements_ecore_x)
+AC_SUBST(requirements_ecore_win32)
+AC_SUBST(requirements_ecore_wince)
+
+AC_OUTPUT([
+Makefile
+ecore-con.pc
+ecore-config.pc
+ecore-directfb.pc
+ecore-evas.pc
+ecore-fb.pc
+ecore-file.pc
+ecore-cocoa.pc
+ecore-imf.pc
+ecore-imf-evas.pc
+ecore-ipc.pc
+ecore-x.pc
+ecore-input.pc
+ecore-input-evas.pc
+ecore-win32.pc
+ecore-sdl.pc
+ecore-wince.pc
+ecore.pc
+doc/ecore.dox
+doc/Makefile
+src/Makefile
+src/bin/Makefile
+src/lib/Makefile
+src/lib/ecore/Makefile
+src/lib/ecore_con/Makefile
+src/lib/ecore_config/Makefile
+src/lib/ecore_directfb/Makefile
+src/lib/ecore_evas/Makefile
+src/lib/ecore_fb/Makefile
+src/lib/ecore_file/Makefile
+src/lib/ecore_cocoa/Makefile
+src/lib/ecore_sdl/Makefile
+src/lib/ecore_imf/Makefile
+src/lib/ecore_imf_evas/Makefile
+src/lib/ecore_input/Makefile
+src/lib/ecore_input_evas/Makefile
+src/lib/ecore_ipc/Makefile
+src/lib/ecore_win32/Makefile
+src/lib/ecore_wince/Makefile
+src/lib/ecore_x/Makefile
+src/lib/ecore_x/xlib/Makefile
+src/lib/ecore_x/xcb/Makefile
+src/tests/Makefile
+README
+ecore.spec
+po/Makefile.in
+])
+
+echo
+echo "$PACKAGE $VERSION"
+echo
+echo "Optional Modules:"
+echo
+echo " Core:"
+echo
+echo " Ecore........................: always"
+echo " Thread support.............: $have_pthread"
+echo " GLib support...............: $have_glib"
+echo " Always integrate GLib......: $want_glib_integration_always"
+echo " Gathering memory statistic.: $have_mallinfo"
+echo " Ecore_Con....................: $have_ecore_con"
+if test "x$have_ecore_con" = "xyes" ; then
+ echo $ECHO_N " OpenSSL....................: $have_openssl $ECHO_C"
+if test "x$have_gnutls" = "xyes" ; then
+ echo " (disabled)"
+else
+ echo
+fi
+ echo " GnuTLS.....................: $have_gnutls"
+ echo " CURL.......................: $have_curl"
+ echo " Abstract Sockets...........: $want_abstract_sockets"
+ echo " c-ares.....................: $have_cares"
+fi
+echo " Ecore_Ipc....................: $have_ecore_ipc"
+if test "x$have_ecore_ipc" = "xyes" ; then
+ echo $ECHO_N " OpenSSL....................: $have_openssl $ECHO_C"
+if test "x$have_gnutls" = "xyes" ; then
+ echo " (disabled)"
+else
+ echo
+fi
+ echo " GnuTLS.....................: $have_gnutls"
+fi
+echo " Ecore_File...................: $have_ecore_file"
+if test "x$have_ecore_file" = "xyes" ; then
+ echo " Inotify....................: $have_inotify"
+ echo " Windows notification.......: $have_notify_win32"
+ echo " Poll.......................: $have_poll"
+ echo " CURL.......................: $have_curl"
+fi
+echo " Ecore_Config.................: $have_ecore_config (deprecated)"
+echo " Ecore_IMF....................: $have_ecore_imf"
+echo " Ecore_IMF_Evas...............: $have_ecore_imf_evas"
+echo " Ecore_Input..................: $have_ecore_input"
+echo " Ecore_Input_Evas.............: $have_ecore_input_evas"
+
+echo
+echo " Graphic systems:"
+echo
+
+if test "x$have_ecore_x" = "xyes" ; then
+ if test "x$have_ecore_x_xcb" = "xyes" ; then
+ echo " Ecore_X (XCB backend)........: $have_ecore_x_xcb"
+ echo " Xprint.....................: $have_ecore_x_xcb_xprint"
+ echo " Xinerama...................: $have_ecore_x_xcb_xinerama"
+ echo " Xrandr.....................: $have_ecore_x_xcb_randr"
+ echo " Xscreensaver...............: $have_ecore_x_xcb_screensaver"
+ echo " Xshape.....................: $have_ecore_x_xcb_shape"
+ echo " Xsync......................: $have_ecore_x_xcb_sync"
+ echo " Xrender....................: $have_ecore_x_xcb_render"
+ echo " Xcomposite.................: $have_ecore_x_xcb_composite"
+ echo " Xfixes.....................: $have_ecore_x_xcb_xfixes"
+ echo " Xdamage....................: $have_ecore_x_xcb_damage"
+ echo " Xdpms......................: $have_ecore_x_xcb_dpms"
+ echo " Xtest......................: $have_ecore_x_xcb_xtest"
+ else
+ echo " Ecore_X (Xlib backend).......: $have_ecore_x"
+ echo " Xcursor....................: $use_Xcursor"
+ echo " Xkb........................: $use_xkb"
+ echo " Xprint.....................: $use_xprint"
+ echo " Xinerama...................: $use_xinerama"
+ echo " Xrandr.....................: $use_xrandr"
+ echo " Xscreensaver...............: $use_xss"
+ echo " Xrender....................: $use_xrender"
+ echo " Xcomposite.................: $use_xcomposite"
+ echo " Xfixes.....................: $use_xfixes"
+ echo " Xdamage....................: $use_xdamage"
+ echo " Xdpms......................: $use_xdpms"
+ echo " Xtest......................: $use_xtest"
+ echo " XIM........................: $want_xim"
+ echo " Xi2........................: $use_xi2"
+ fi
+else
+ echo " Ecore_X......................: $have_ecore_x"
+fi
+echo " Ecore_Win32..................: $have_ecore_win32"
+echo " Ecore_Cocoa..................: $have_ecore_cocoa"
+echo " Ecore_SDL....................: $have_ecore_sdl"
+echo " Ecore_FB.....................: $have_ecore_fb"
+if test "x${have_ecore_fb}" = "xyes" ; then
+ echo " Touchscreen................: $have_tslib"
+fi
+echo " Ecore_DirectFB...............: $have_ecore_directfb"
+echo " Ecore_WinCE..................: $have_ecore_wince"
+
+echo
+echo " Ecore Evas:"
+echo
+
+echo " Ecore_Evas...................: $have_ecore_evas"
+if test "x${have_ecore_evas}" = "xyes" ; then
+ echo " Software Memory Buffer.....: $have_ecore_evas_software_buffer"
+ if test "x${have_ecore_evas_software_x11}" = "xyes" ; then
+ echo " Software X11...............: $have_ecore_evas_software_x11 (Xlib=${have_ecore_evas_software_xlib}) (XCB=${have_ecore_evas_software_xcb})"
+ else
+ echo " Software X11...............: $have_ecore_evas_software_x11"
+ fi
+ echo " XRender X11................: $have_ecore_evas_xrender_x11"
+ echo " OpenGL X11.................: $have_ecore_evas_opengl_x11"
+ echo " XRender XCB................: $have_ecore_evas_xrender_xcb"
+ echo " Software GDI...............: $have_ecore_evas_software_gdi"
+ echo " Software DirectDraw........: $have_ecore_evas_software_ddraw"
+ echo " Direct3D...................: $have_ecore_evas_direct3d"
+ echo " OpenGL Glew................: $have_ecore_evas_opengl_glew"
+ echo " Cocoa......................: $have_ecore_evas_cocoa"
+ echo " Software SDL...............: $have_ecore_evas_software_sdl"
+ echo " OpenGL SDL.................: $have_ecore_evas_opengl_sdl"
+ echo " DirectFB...................: $have_ecore_evas_directfb"
+ echo " Software Framebuffer.......: $have_ecore_evas_fb"
+ echo " Software 16bit X11.........: $have_ecore_evas_software_16_x11"
+ echo " Software 16bit DirectDraw..: $have_ecore_evas_software_16_ddraw"
+ echo " Software 16bit WinCE.......: $have_ecore_evas_software_16_wince"
+fi
+echo
+echo " Tests................: ${enable_tests}"
+echo " Maximum log level....: ${with_max_log_level}"
+echo "Documentation..........: ${build_doc}"
+echo
+echo "Compilation............: make (or gmake)"
+echo " CPPFLAGS.............: $CPPFLAGS"
+echo " CFLAGS...............: $CFLAGS"
+echo " CXXFLAGS.............: $CXXFLAGS"
+echo " LDFLAGS..............: $LDFLAGS"
+echo
+echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')"
+echo " prefix...............: $prefix"
+echo
--- /dev/null
+Revision 48959
+Last Changed Rev 48958
--- /dev/null
+ecore (0.9.9.060+svnYYYYMMDD-1) unstable; urgency=low
+
+ * New version
+
+ -- quaker <quaker66@gmail.com> Thu, 22 Apr 2009 18:12:06 +0100
+
+ecore (0.9.9.050+svnYYYYMMDD-1) unstable; urgency=low
+
+ * Clean up changelog
+
+ -- quaker <quaker66@gmail.com> Tue, 21 Apr 2009 19:14:37 +0100
--- /dev/null
+Source: ecore
+Section: libs
+Priority: optional
+Maintainer: Debian Pkg-e Team <pkg-e-devel@lists.alioth.debian.org>
+Uploaders: Albin Tonnerre <albin.tonnerre@gmail.com>, Niv Sardi <xaiki@debian.org>,
+ Xavier Oswald <x.oswald@free.fr>, Jan Lübbe <jluebbe@debian.org>
+Build-Depends: dpkg-dev (>= 1.14.8), debhelper (>= 6), cdbs, libeina-dev (>= 0.0.2.060+svnYYYYMMDD),
+ libeet-dev (>= 1.0.0), libevas-dev (>= 0.9.9.060+svnYYYYMMDD), libgnutls-dev,
+ libcurl4-gnutls-dev, libxcursor-dev, libxss-dev, libxrender-dev, libxinerama-dev,
+ libxrandr-dev, libxext-dev, libxp-dev, libxcomposite-dev, libjpeg62-dev,
+ libxdamage-dev, x11proto-xext-dev, libxtst-dev, doxygen, pkg-config, libtool
+Standards-Version: 3.8.1
+Homepage: http://enlightenment.org
+
+Package: libecore-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Core abstraction layer for enlightenment DR 0.17
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+
+Package: libecore-con-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore Connection Library
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore Connection Library.
+
+Package: libecore-config-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore Enlightened Property Library
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Enlightened Property Library.
+
+Package: libecore-evas-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore Evas Wrapper Library
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore Evas wrapper functions.
+
+Package: libecore-fb-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore frame buffer system functions
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore frame buffer system functions.
+
+Package: libecore-file-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore File Library
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore File Library.
+
+Package: libecore-imf-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore Input Method Framework module
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore Input Method Framework module, and the Evas
+ helper functions for it.
+
+Package: libecore-input-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore input functions
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore Input Library.
+
+Package: libecore-ipc-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore inter-process communication functions
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore inter-process communication functions.
+
+Package: libecore-x-svn-01
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Ecore functions for dealing with the X Windows System
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains the Ecore wrapper and convenience functions for using
+ the X Windows System.
+
+Package: libecore-dev
+Architecture: any
+Section: libdevel
+Suggests: libecore-doc
+Depends: ${misc:Depends}, libecore-svn-01 (= ${binary:Version}),
+ libecore-con-svn-01 (= ${binary:Version}),
+ libecore-config-svn-01 (= ${binary:Version}),
+ libecore-evas-svn-01 (= ${binary:Version}),
+ libecore-fb-svn-01 (= ${binary:Version}),
+ libecore-file-svn-01 (= ${binary:Version}),
+ libecore-imf-svn-01 (= ${binary:Version}),
+ libecore-input-svn-01 (= ${binary:Version}),
+ libecore-ipc-svn-01 (= ${binary:Version}),
+ libecore-x-svn-01 (= ${binary:Version}),
+ libeet-dev, libevas-dev (>= 0.9.9.060), libeina-dev, pkg-config,
+ libgnutls-dev, libcurl4-gnutls-dev, libxcursor-dev, libxss-dev,
+ libxrender-dev, libxinerama-dev, libxrandr-dev, libxext-dev,
+ libxp-dev, libxcomposite-dev, libxdamage-dev, x11proto-xext-dev, libxtst-dev
+Description: Ecore headers and static libraries
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package contains headers and static libraries for the Ecore library.
+
+Package: libecore-doc
+Architecture: all
+Section: doc
+Depends: ${misc:Depends}
+Enhances: libecore-dev
+Description: Ecore API Documentation
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package provides development documentation (html and manpages)for the
+ Ecore library.
+
+Package: libecore-bin
+Architecture: any
+Section: utils
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Tools that support Ecore
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications.
+ .
+ This package includes:
+ - ecore_config: allows creation/editing of ecore_config databases
+
+Package: libecore-dbg
+Architecture: any
+Section: libdevel
+Priority: extra
+Depends: ${misc:Depends}, libecore-svn-01 (= ${binary:Version})
+Description: Debugging symbols for libecore
+ This is the core event abstraction layer and X abstraction layer that makes
+ doing selections, Xdnd, general X stuff, and event loops, timeouts and idle
+ handlers fast, optimized, and convenient. It's a separate library so anyone
+ can make use of the work put into Ecore to make this job easy for
+ applications
+ .
+ This package contains unstripped shared libraries. It is provided primarily
+ to provide a backtrace with names in a debugger, this makes it somewhat easier
+ to interpret core dumps. The libraries are installed in /usr/lib/debug and
+ are automatically used by gdb.
--- /dev/null
+This package was debianized by Debian Pkg-e Team <pkg-e-devel@lists.alioth.debian.org>
+Sat, 07 Jul 2007 09:29:10 +0000.
+
+It was downloaded from http://download.enlightenment.org/
+
+Upstream Authors:
+
+ Enlightenment team <enlightenment-devel@lists.sourceforge.net>
+
+Copyright:
+
+ Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS)
+
+ Additional Copyright:
+ src/lib/ecore/ecore_str.c: Copyright (c) 1998 Todd C. Miller
+ <Todd.Miller@courtesan.com>
+ src/lib/ecore/ecore_value.c: Copyright (C) 2001
+ Christopher Rosendahl <smugg@fatelabs.com>
+ Nathan Ingersoll <ningerso@d.umn.edu>
+ src/lib/ecore_fb/ecore_fb_li.c: Copyright (C) 1999-2002 Brad Hards
+
+License:
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies 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.
+
+On Debian systems, the complete text of the BSD License can be found
+in `/usr/share/common-licenses/BSD'.
--- /dev/null
+.\"Created with GNOME Manpages Editor Wizard
+.\"http://gmanedit.sourceforge.net
+.\"Sergio Rua <srua@gpul.org>
+.\"
+.TH ecore_config 1 "January 18, 2007" "Ecore"
+
+.SH NAME
+ecore_config \-that allow creation and editing of ecore_config databases
+
+.SH SYNOPSIS
+.B ecore_config
+.RI \-a\ |\ \-k\ [\-g|\-d|\-b|\-f|\-i|\-r|\-s|\-t]\ [\-c]
+.br
+
+.SH DESCRIPTION
+.PP
+\fBecore_config\fP is a tool that allows creation and editing of
+ecore_config databases used by the programs relying on libecore
+
+.SH OPTIONS
+\fIecore_config\fP accepts the following options:
+.TP
+.B \-c, \-\-file=FILE
+Specify the config file to read
+.TP
+.B \-k, \-\-key=KEY
+Select the key KEY. Must be given for all commands except \-a
+.TP
+.B \-g, \-\-get
+get key
+.TP
+.B \-d, \-\-del
+delete key
+.TP
+.B \-b, \-\-bool=VALUE
+set boolean
+.TP
+.B \-f, \-\-float=VALUE
+set float
+.TP
+.B \-i, \-\-int=VALUE
+set integer
+.TP
+.B \-r, \-\-rgb=VALUE
+set RGBA
+.TP
+.B \-s, \-\-string=VALUE
+set string
+.TP
+.B \-t, \-\-theme=VALUE
+set theme
+.SH AUTHOR
+This manual page was written by Albin Tonnerre <albin.tonnerre@gmail.com>
+for the Debian GNU/Linux system (but may be used by others).
--- /dev/null
+debian/tmp/usr/bin/ecore_config
--- /dev/null
+debian/tmp/usr/lib/libecore_con-*.so.*
--- /dev/null
+libecore_con-ver-pre-svn-01 0 libecore-con-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore_config-*.so.*
--- /dev/null
+libecore_config-ver-pre-svn-01 0 libecore-config-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/include/Ecore*.h
+debian/tmp/usr/lib/libecore*.a
+debian/tmp/usr/lib/libecore.so
+debian/tmp/usr/lib/libecore_config.so
+debian/tmp/usr/lib/libecore_con.so
+debian/tmp/usr/lib/libecore_evas.so
+debian/tmp/usr/lib/libecore_fb.so
+debian/tmp/usr/lib/libecore_file.so
+debian/tmp/usr/lib/libecore_imf_evas.so
+debian/tmp/usr/lib/libecore_imf.so
+debian/tmp/usr/lib/libecore_input.so
+debian/tmp/usr/lib/libecore_ipc.so
+debian/tmp/usr/lib/libecore_x.so
+debian/tmp/usr/lib/pkgconfig/ecore*.pc
--- /dev/null
+Document: ecore
+Title: Ecore Guide
+Author: Carsten Haitzler
+Abstract: This document describes Ecore API
+ and provides sample C code.
+Section: Programming/C
+
+Format: HTML
+Index: /usr/share/doc/libecore-doc/html/index.html
+Files: /usr/share/doc/libecore-doc/html/*.html
--- /dev/null
+debian/tmp/usr/lib/libecore_evas-*.so.*
--- /dev/null
+libecore_evas-ver-pre-svn-01 0 libecore-evas-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore_fb-*.so.*
--- /dev/null
+libecore_fb-ver-pre-svn-01 0 libecore-fb-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore_file-*.so.*
--- /dev/null
+libecore_file-ver-pre-svn-01 0 libecore-file-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore_imf-*.so.*
+debian/tmp/usr/lib/libecore_imf_evas-*.so.*
--- /dev/null
+libecore_imf-ver-pre-svn-01 0 libecore-imf-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
+libecore_imf_evas-ver-pre-svn-01 0 libecore-imf-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore_input-*.so.*
--- /dev/null
+libecore_input-ver-pre-svn-01 0 libecore-input-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore_ipc-*.so.*
--- /dev/null
+libecore_ipc-ver-pre-svn-01 0 libecore-ipc-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore-*.so.*
--- /dev/null
+libecore-ver-pre-svn-01 0 libecore-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+debian/tmp/usr/lib/libecore_x-*.so.*
--- /dev/null
+libecore_x-ver-pre-svn-01 0 libecore-x-svn-01 (>= 0.9.9.060+svnYYYYMMDD)
--- /dev/null
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/class/autotools.mk
+include /usr/share/cdbs/1/rules/debhelper.mk
+
+DEB_CONFIGURE_SCRIPT := ./autogen.sh
+DEB_INSTALL_MANPAGES_libecore-bin := debian/ecore_config.1
+DEB_DH_STRIP_ARGS := --dbg-package=libecore-dbg
+DEB_CONFIGURE_EXTRA_FLAGS := --enable-ecore-fb \
+ --disable-ecore-directfb \
+ --disable-ecore-evas-dfb \
+ --enable-ecore-evas-fb \
+ --disable-rpath \
+ --disable-openssl \
+ --enable-gnutls \
+ --enable-doc
+DEB_MAKE_CLEAN_TARGET := distclean
+CFLAGS += -fvisibility=hidden
+LDFLAGS += -fvisibility=hidden
+
+build/libecore-doc::
+ cd $(DEB_SRCDIR)/doc && make doc
+
+install/libecore-doc::
+ mkdir -p debian/libecore-doc/usr/share/doc/libecore-doc
+ cp -R $(DEB_SRCDIR)/doc/html debian/libecore-doc/usr/share/doc/libecore-doc/
+
+clean::
+ [ ! -f Makefile ] || make distclean
+ rm -f ecore-*.tar.bz2 ecore-*.tar.bz2.cdbs-config_list
--- /dev/null
+html
+latex
+man
--- /dev/null
+PROJECT_NAME = Ecore
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = .
+INPUT = ./ecore.dox ../src/lib
+IMAGE_PATH = img
+OUTPUT_LANGUAGE = English
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = head.html
+HTML_FOOTER = foot.html
+HTML_STYLESHEET = e.css
+HTML_ALIGN_MEMBERS = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = YES
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+INTERNAL_DOCS = NO
+STRIP_CODE_COMMENTS = YES
+CASE_SENSE_NAMES = YES
+SHORT_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+VERBATIM_HEADERS = NO
+SHOW_INCLUDE_FILES = NO
+JAVADOC_AUTOBRIEF = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 2
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ALIASES =
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+SHOW_USED_FILES = NO
+QUIET = YES
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+FILE_PATTERNS =
+RECURSIVE = YES
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH = ../examples/
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+INPUT_FILTER =
+FILTER_SOURCE_FILES = NO
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 2
+IGNORE_PREFIX =
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+GENERATE_LATEX = YES
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+GENERATE_MAN = YES
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = YES
+GENERATE_XML = NO
+XML_SCHEMA =
+XML_DTD =
+GENERATE_AUTOGEN_DEF = NO
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = NO
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+CLASS_DIAGRAMS = NO
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = NO
+COLLABORATION_GRAPH = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = NO
+INCLUDED_BY_GRAPH = NO
+GRAPHICAL_HIERARCHY = NO
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 512
+MAX_DOT_GRAPH_HEIGHT = 512
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+SEARCHENGINE = NO
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in ecore.dox
+
+.PHONY: doc
+
+PACKAGE_DOCNAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-doc
+
+if EFL_BUILD_DOC
+
+doc-clean:
+ rm -rf html/ latex/ man/ xml/ $(PACKAGE_DOCNAME).tar*
+
+doc: all doc-clean
+ $(efl_doxygen)
+ cp img/* html/
+ rm -rf $(PACKAGE_DOCNAME).tar*
+ mkdir -p $(PACKAGE_DOCNAME)/doc
+ cp -R html/ latex/ man/ $(PACKAGE_DOCNAME)/doc
+ tar cf $(PACKAGE_DOCNAME).tar $(PACKAGE_DOCNAME)/
+ bzip2 -9 $(PACKAGE_DOCNAME).tar
+ rm -rf $(PACKAGE_DOCNAME)/
+ mv $(PACKAGE_DOCNAME).tar.bz2 $(top_srcdir)
+
+clean-local: doc-clean
+
+else
+
+doc:
+ @echo "Documentation not built. Run ./configure --help"
+
+endif
+
+EXTRA_DIST = Doxyfile $(wildcard img/*.*) e.css head.html foot.html ecore.dox.in
--- /dev/null
+/*
+ Author:
+ Andres Blanc <andresblanc@gmail.com>
+ DaveMDS Andreoli <dave@gurumeditation.it>
+
+ Supported Browsers:
+ ie7, opera9, konqueror4 and firefox3
+
+ Please use a different file for ie6, ie5, etc. hacks.
+*/
+
+
+/* Necessary to place the footer at the bottom of the page */
+html, body {
+ height: 100%;
+ margin: 0px;
+ padding: 0px;
+}
+
+#container {
+ min-height: 100%;
+ height: auto !important;
+ height: 100%;
+ margin: 0 auto -53px;
+}
+
+#footer, #push {
+ height: 53px;
+}
+
+
+* html #container {
+ height: 100%;
+}
+
+/* Prevent floating elements overflowing containers */
+.clear {
+ clear: both;
+ width: 0px;
+ height: 0px;
+}
+
+/* Flexible & centered layout from 750 to 960 pixels */
+.layout {
+ max-width: 960px;
+ min-width: 760px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+body {
+ /*font-family: Lucida Grande, Helvetica, sans-serif;*/
+ font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif
+}
+
+/* Prevent design overflowing the viewport in small resolutions */
+#container {
+ padding-right: 17px;
+ padding-left: 17px;
+ background-image: url(head_bg.png);
+ background-repeat: repeat-x;
+}
+
+/****************************/
+/* Top main menu */
+/****************************/
+#header_logo {
+ background-image : url(logo.png);
+ width : 61px;
+}
+
+#header_logo a {
+ position : absolute;
+ border : 0px;
+ background-color : transparent;
+ top : 0px;
+ width : 60px;
+ height : 60px;
+}
+
+#header_menu {
+ background-image : url(header_menu_background.png);
+ font : normal 10pt verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif;
+ text-align : right;
+}
+
+#header_last {
+ background-image : url(header_menu_background_last.png);
+ width : 15px;
+}
+
+td.nav_passive {
+ background : url(header_menu_unselected_background.png) 0 0 no-repeat;
+ height : 63px;
+ font-family : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif;
+ font-size : 11px;
+ padding : 20px 10px 20px 10px;
+ vertical-align : middle;
+}
+
+td.nav_active {
+ background : url(header_menu_current_background.png) 0 0 no-repeat;
+ height : 63px;
+ color : #646464;
+ font-family : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif;
+ font-size : 11px;
+ font-weight : bold;
+ padding : 20px 10px 20px 10px;
+ vertical-align : middle;
+}
+
+#header_menu a {
+ display : block;
+ text-decoration : none;
+ cursor : pointer;
+ color : #cdcdcd;
+}
+
+
+
+#header {
+ width: 100%;
+ height: 102px;
+}
+
+#header h1 {
+ width: 63px;
+ height: 63px;
+ position: absolute;
+ margin: 0px;
+}
+
+#header h1 span {
+ display: none;
+}
+
+#header h2 {
+ display: none;
+}
+
+/* .menu-container is used to set properties common to .menu and .submenu */
+#header .menu-container {
+}
+
+#header .menu-container ul {
+ list-style-type: none;
+ list-style-position: inside;
+ margin: 0;
+}
+
+#header .menu-container li {
+ display: block;
+ float: right;
+}
+
+#header .menu {
+ height: 63px;
+ display: block;
+ background-image: url(menu_bg.png);
+ background-repeat: repeat-x;
+}
+
+#header .menu ul {
+ height: 100%;
+ display: block;
+ background-image: url(menu_bg_last.png);
+ background-repeat: no-repeat;
+ background-position: top right;
+ padding-right: 17px;
+}
+
+#header .menu li {
+ height: 100%;
+ text-align: center;
+ background-image: url(menu_bg_unsel.png);
+ background-repeat: no-repeat;
+}
+
+#header .menu a {
+ height: 100%;
+ display: block;
+ color: #cdcdcd;
+ text-decoration: none;
+ font-size: 10pt;
+ line-height: 59px;
+ text-align: center;
+ padding: 0px 15px 0px 15px;
+}
+
+#header .menu li:hover {
+ background-image: url(menu_bg_hover.png);
+ background-repeat: no-repeat;
+}
+
+#header .menu li:hover a {
+ color: #FFFFFF;
+}
+
+#header .menu li.current {
+ background-image: url(menu_bg_current.png);
+ background-repeat: no-repeat;
+}
+
+#header .menu li.current a {
+ color: #646464;
+}
+
+
+/* Hide all the submenus but the current */
+#header .submenu ul {
+ display: none;
+}
+
+#header .submenu .current {
+ display: block;
+}
+
+#header .submenu {
+ font: bold 10px verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif;
+ margin-top: 10px;
+}
+
+#header .submenu a {
+ color: #888888;
+ text-decoration: none;
+ font-size: 0.9em;
+ line-height: 15px;
+ padding:0px 5px 0px 5px;
+}
+
+#header .submenu a:hover {
+ color: #444444;
+}
+
+#header .submenu li {
+ border-left: 1px solid #DDDDDD;
+}
+
+#header .submenu li:last-child {
+ border-left: 0;
+}
+
+#header .doxytitle {
+ position: absolute;
+ font-size: 1.8em;
+ font-weight: bold;
+ color: #444444;
+ line-height: 35px;
+}
+
+#header small {
+ font-size: 0.4em;
+}
+
+#footer {
+ background-image: url(foot_bg.png);
+ width: 100%;
+}
+
+#footer table {
+ width: 100%;
+ text-align: center;
+ white-space: nowrap;
+ padding: 5px 30px 5px 30px;
+ font-size: 0.8em;
+ font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif;
+ color: #888888;
+}
+
+#footer td.copyright {
+ width: 100%;
+}
+
--- /dev/null
+/**
+@brief Ecore Library Public API Calls
+
+These routines are used for Ecore Library interaction
+*/
+
+/**
+
+@mainpage Ecore
+
+@image html e.png
+
+@version @PACKAGE_VERSION@
+@author Carsten Haitzler <raster\@rasterman.com>
+@author Tom Gilbert <tom\@linuxbrit.co.uk>
+@author Burra <burra\@colorado.edu>
+@author Chris Ross <chris\@darkrock.co.uk>
+@author Term <term\@twistedpath.org>
+@author Tilman Sauerbeck <tilman\@code-monkey.de>
+@author Nathan Ingersoll <rbdpngn\@users.sourceforge.net>
+@date 2000-2004
+
+@section intro Introduction
+
+Ecore is a library of convenience functions.
+
+The Ecore library provides the following modules:
+@li @link Ecore.h Ecore - Main Loop and Job Functions. @endlink
+@li @link Ecore_Con.h Ecore_Con - Connection functions. @endlink
+@li @link Ecore_Config.h Ecore_Config - Configuration functions. @endlink
+@li @link Ecore_Evas.h Ecore_Evas - Evas convenience functions. @endlink
+@li @link Ecore_Fb.h Ecore_FB - Frame buffer convenience functions. @endlink
+@li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink
+@li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink
+
+@section compiling How to compile using Ecore?
+
+This section has to be documented. Below is just a quick line to handle all
+Ecore modules at once.
+
+@verbatim
+gcc *.c \
+-I/usr/local/include -I/usr/X11R6/include \
+-L/usr/local/lib -L/usr/X11R6/lib \
+-lecore -lecore_evas -lecore_x -lecore_fb \
+`pkg-config evas --cflags --libs`
+@endverbatim
+
+@section install How is it installed?
+
+Suggested configure options for evas for a Linux desktop X display:
+
+@verbatim
+./configure \
+--enable-ecore-x \
+--enable-ecore-fb \
+--enable-ecore-evas \
+--enable-ecore-evas-gl \
+--enable-ecore-con \
+--enable-ecore-ipc
+make CFLAGS="-O9 -mpentiumpro -march=pentiumpro -mcpu=pentiumpro"
+@endverbatim
+
+@todo (1.0) Document API
+
+*/
+
+/*
+@page Ecore_Main_Loop_Page The Ecore Main Loop
+
+@section intro What is Ecore?
+
+Ecore is a clean and tiny event loop library with many modules to do lots of
+convenient things for a programmer, to save time and effort.
+
+It's small and lean, designed to work on embedded systems all the way to
+large and powerful multi-cpu workstations. It serialises all system signals,
+events etc. into a single event queue, that is easily processed without
+needing to worry about concurrency. A properly written, event-driven program
+using this kind of programming doesn't need threads, nor has to worry about
+concurrency. It turns a program into a state machine, and makes it very
+robust and easy to follow.
+
+Ecore gives you other handy primitives, such as timers to tick over for you
+and call specified functions at particular times so the programmer can use
+this to do things, like animate, or time out on connections or tasks that take
+too long etc.
+
+Idle handlers are provided too, as well as calls on entering an idle state
+(often a very good time to update the state of the program). All events that
+enter the system are passed to specific callback functions that the program
+sets up to handle those events. Handling them is simple and other Ecore
+modules produce more events on the queue, coming from other sources such as
+file descriptors etc.
+
+Ecore also lets you have functions called when file descriptors become active
+for reading or writing, allowing for streamlined, non-blocking IO.
+
+Here is an exmaple of a simple program and its basic event loop flow:
+
+@image html prog_flow.png
+
+
+
+@section work How does Ecore work?
+
+Ecore is very easy to learn and use. All the function calls are designed to
+be easy to remember, explicit in describing what they do, and heavily
+name-spaced. Ecore programs can start and be very simple.
+
+For example:
+
+@code
+#include <Ecore.h>
+
+int main(int argc, const char **argv)
+{
+ ecore_init();
+ ecore_app_args_set(argc, argv);
+ ecore_main_loop_begin();
+ ecore_shutdown();
+ return 0;
+}
+@endcode
+
+This program is very simple and does't check for errors, but it does start up
+and begin a main loop waiting for events or timers to tick off. This program
+doesn't set up any, but now we can expand on this simple program a little
+more by adding some event handlers and timers.
+
+@code
+#include <Ecore.h>
+
+Ecore_Timer *timer1 = NULL;
+Ecore_Event_Handler *handler1 = NULL;
+double start_time = 0.0;
+
+int timer_func(void *data)
+{
+ printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time);
+ return 1;
+}
+
+int exit_func(void *data, int ev_type, void *ev)
+{
+ Ecore_Event_Signal_Exit *e;
+
+ e = (Ecore_Event_Signal_Exit *)ev;
+ if (e->interrupt) printf("Exit: interrupt\n");
+ else if (e->quit) printf("Exit: quit\n");
+ else if (e->terminate) printf("Exit: terminate\n");
+ ecore_main_loop_quit();
+ return 1;
+}
+
+int main(int argc, const char **argv)
+{
+ ecore_init();
+ ecore_app_args_set(argc, argv);
+ start_time = ecore_time_get();
+ handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL);
+ timer1 = ecore_timer_add(0.5, timer_func, NULL);
+ ecore_main_loop_begin();
+ ecore_shutdown();
+ return 0;
+}
+@endcode
+
+In the previous example, we initialize our application and get the time at
+which our program has started so we can calculate an offset. We set
+up a timer to tick off in 0.5 seconds, and since it returns 1, will
+keep ticking off every 0.5 seconds until it returns 0, or is deleted
+by hand. An event handler is set up to call a function - exit_func(),
+whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C
+on the command line will cause such an event to happen). If this event
+occurs it tells you what kind of exit signal was received, and asks
+the main loop to quit when it is finished by calling
+ecore_main_loop_quit().
+
+The handles returned by ecore_timer_add() and ecore_event_handler_add() are
+only stored here as an example. If you don't need to address the timer or
+event handler again you don't need to store the result, so just call the
+function, and don't assign the result to any variable.
+
+This program looks slightly more complex than needed to do these simple
+things, but in principle, programs don't get any more complex. You add more
+event handlers, for more events, will have more timers and such, BUT it all
+follows the same principles as shown in this example.
+
+*/
+
+/**
+@page Ecore_Config_Page The Enlightened Property Library
+
+The Enlightened Property Library (Ecore_Config) is an adbstraction
+from the complexities of writing your own configuration. It provides
+many features using the Enlightenment 17 development libraries.
+
+To use the library, you:
+@li Set the default values of your properties.
+@li Load the configuration from a file. You must set the default values
+ first, so that the library knows the correct type of each argument.
+
+The following examples show how to use the Enlightened Property Library:
+@li @link config_basic_example.c config_basic_example.c @endlink
+@li @link config_listener_example.c config_listener_example.c @endlink
+
+*/
+
+/**
+@page Ecore_ADT_Page Ecore Abstract Data Types
+
+This page briefly describes the different abstract data types
+that are provided by the Ecore library for general usage. You need to
+include the @link Ecore_Data.h Ecore_Data.h @endlink to use them.
+
+@section Ecore_ADT_List List
+
+A list is a simple data type where one each piece of data points to
+another piece of data.
+
+Associated modules that describe the List ADT include:
+@li @ref Ecore_Data_List_Creation_Group
+@li @ref Ecore_Data_List_Add_Item_Group
+@li @ref Ecore_Data_List_Remove_Item_Group
+@li @ref Ecore_Data_List_Traverse_Group
+@li @ref Ecore_Data_List_Node_Group
+
+Examples involving lists include:
+@li @link list_example.c list_example.c @endlink
+
+@section Ecore_ADT_DList Doubly Linked List
+
+A doubly linked list is like a linked list, only each piece of data
+can also point to the piece before it. In other words, you can traverse
+a doubly linked list in both directions.
+
+Associated modules that describe the DList ADT include:
+@li @ref Ecore_Data_DList_Creation_Group
+@li @ref Ecore_Data_DList_Add_Item_Group
+@li @ref Ecore_Data_DList_Remove_Item_Group
+
+@section Ecore_ADT_Hash Hash
+
+A hash is an abstract data type where one value is associated with another
+value. Instead of each element of the group being accessible using a
+number, each element is accessed using another object.
+
+Associated modules that describe the Hash ADT include:
+@li @ref Ecore_Data_Hash_ADT_Creation_Group
+@li @ref Ecore_Data_Hash_ADT_Destruction_Group
+@li @ref Ecore_Data_Hash_ADT_Data_Group
+
+@todo Finish this.
+*/
+
+/**
+@page X_Window_System_Page X Window System
+
+The Ecore library includes a wrapper for handling the X window system.
+This page briefly explains what the X window system is and various terms
+that are used.
+*/
+
+// GROUP DEFINITIONS
+
+/**
+@defgroup Ecore_Timer_Group Ecore Timer
+
+The timer allows callbacks to be called at specific intervals.
+ */
+
+/**
+@defgroup Ecore_Job_Group Ecore Jobs
+
+You can queue jobs that are to be done by the main loop when the current
+event is dealt with.
+*/
+
+/**
+@defgroup Idle_Group Idle Handlers
+
+Callbacks that are called when the program enters or exits an idle state.
+
+The ecore main loop enters an idle state when it is waiting for timers
+to time out, data to come in on a file descriptor or any other event
+to occur. You can set callbacks to be called when the main loop
+enters an idle state, during an idle state or just after the program
+wakes up.
+
+Enterer callbacks are good for updating your program's state, if it
+has a state engine. Once all of the enterer handlers are called, the
+program will enter a "sleeping" state.
+
+Idler callbacks are called when the main loop has called all enterer
+handlers. They are useful for interfaces that require polling and
+timers would be too slow to use.
+
+If no idler callbacks are specified, then the process literally goes
+to sleep. Otherwise, the idler callbacks are called continuously
+while the loop is "idle", using as much CPU as is available to the
+process.
+
+Exiter callbacks are called when the main loop wakes up from an idle
+state.
+
+*/
+
+/**
+@defgroup Ecore_Config_Create_Group Ecore Config Create Functions
+
+Convenience functions that set default values, bounds, option values and
+descriptions in one call.
+*/
+
+/**
+@defgroup Ecore_Config_File_Group Ecore Config File Functions
+
+Functions that are used to load and save properties from and to files.
+*/
+
+// EXAMPLES
+
+/**
+@example args_example.c
+Shows how to set and retrieve the program arguments.
+*/
+
+/**
+@example con_server_example.c
+Shows how to write a simple server using the Ecore_Con library.
+*/
+
+/**
+@example con_client_example.c
+Shows how to write a simple client, that connects to the example server.
+*/
+
+/**
+@example event_handler_example.c
+Shows how to use event handlers.
+*/
+
+/**
+@example timer_example.c
+Demonstrates use of the ecore_timer.
+*/
+
+/**
+@example config_basic_example.c
+Provides an example of how to use the basic configuration functions.
+See the file Ecore_Config.h for the full list of available functions.
+*/
+
+/**
+@example config_listener_example.c
+Shows how to set up a listener to listen for configuration changes.
+*/
+
+/**
+@example list_example.c
+Provides a basic example of how to append to and traverse a list.
+*/
+
+/**
+@example list_destroy_example.c
+Shows how to set and use a destructor for an Ecore_List.
+*/
+
+/**
+@example x_window_example.c
+Shows the basics of using the X Windows system through Ecore functions.
+*/
--- /dev/null
+
+ <div id="push"></div>
+ </div> <!-- #content -->
+ </div> <!-- .layout -->
+
+ </div> <!-- #container -->
+
+
+ <div id="footer">
+ <table><tr>
+ <td class="copyright">Copyright ©$year Enlightenment</td>
+ <td class="generated">Docs generated $datetime</td>
+ </tr></table>
+ </div>
+
+
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <title>$title</title>
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8">
+ <meta name="author" content="Andres Blanc" >
+
+ <link rel="icon" href="img/favicon.png" type="image/x-icon">
+ <link rel="shortcut icon" href="img/favicon.png" type="image/x-icon">
+ <link rel="icon" href="img/favicon.png" type="image/ico">
+ <link rel="shortcut icon" href="img/favicon.png" type="image/ico">
+
+ <link rel="stylesheet" type="text/css" href="e.css">
+ <link rel="stylesheet" type="text/css" href="edoxy.css">
+</head>
+
+<body>
+
+<div id="container">
+
+<div id="header">
+<div class="layout">
+
+ <h1><span>Enlightenment</span></h1>
+ <h2><span>Beauty at your fingertips</span></h2>
+
+ <table cellspacing="0" cellpadding="0" width="100%"><tr>
+ <td id="header_logo">
+ <a href="http://www.enlightenment.org"></a>
+ </td>
+ <td id="header_menu">
+ <table cellspacing="0" cellpadding="0" align="right"><tr>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=home">Home</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=news">News</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=about">About</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=download">Download</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=support">Support</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=contribute">Contribute</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=contact">Contact</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://trac.enlightenment.org/e">Tracker</a></td>
+ <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=docs">Docs</a></td>
+ </tr></table>
+ </td>
+ <td id="header_last"></td>
+ </tr></table>
+
+ <div class="doxytitle">
+ $projectname Documentation <small>at $date</small>
+ </div>
+
+ <div class="menu-container">
+ <div class="submenu">
+ <ul class="current">
+ <li><a href="files.html">Files</a></li>
+ <li><a href="annotated.html">Data Structures</a></li>
+ <li><a href="globals.html">Globals</a></li>
+ <li><a href="modules.html">Modules</a></li>
+ <li><a href="pages.html">Related Pages</a></li>
+ <li class="current"><a href="index.html">Main Page</a></li>
+ </ul>
+ </div>
+ </div>
+
+
+ <div class="clear"></div>
+</div>
+</div>
+
+<div id="content">
+<div class="layout">
--- /dev/null
+/*
+ * This file contain a custom doxygen style to match e.org graphics
+ */
+
+
+
+/* BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+}*/
+BODY, TD {
+ font-size: 12px;
+}
+H1 {
+ text-align: center;
+ font-size: 160%;
+}
+H2 {
+ font-size: 120%;
+}
+H3 {
+ font-size: 100%;
+}
+CAPTION {
+ font-weight: bold
+}
+DIV.qindex {
+ width: 100%;
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ padding: 2px;
+ line-height: 140%;
+}
+DIV.navpath {
+ width: 100%;
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ padding: 2px;
+ line-height: 140%;
+}
+DIV.navtab {
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+TD.navtab {
+ font-size: 70%;
+}
+A.qindex {
+ text-decoration: none;
+ font-weight: bold;
+ color: #1A419D;
+}
+A.qindex:visited {
+ text-decoration: none;
+ font-weight: bold;
+ color: #1A419D
+}
+A.qindex:hover {
+ text-decoration: none;
+ background-color: #ddddff;
+}
+A.qindexHL {
+ text-decoration: none;
+ font-weight: bold;
+ background-color: #6666cc;
+ color: #ffffff;
+ border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+ text-decoration: none;
+ background-color: #6666cc;
+ color: #ffffff;
+}
+A.qindexHL:visited {
+ text-decoration: none;
+ background-color: #6666cc;
+ color: #ffffff
+}
+A.el {
+ text-decoration: none;
+ font-weight: bold
+}
+A.elRef {
+ font-weight: bold
+}
+A.code:link {
+ text-decoration: none;
+ font-weight: normal;
+ color: #0000FF
+}
+A.code:visited {
+ text-decoration: none;
+ font-weight: normal;
+ color: #0000FF
+}
+A.codeRef:link {
+ font-weight: normal;
+ color: #0000FF
+}
+A.codeRef:visited {
+ font-weight: normal;
+ color: #0000FF
+}
+A:hover, A:visited:hover {
+ text-decoration: none;
+ /* background-color: #f2f2ff; */
+ color: #000055;
+}
+A.anchor {
+ color: #000;
+}
+DL.el {
+ margin-left: -1cm
+}
+.fragment {
+ font-family: monospace, fixed;
+ font-size: 95%;
+}
+PRE.fragment {
+ border: 1px solid #CCCCCC;
+ background-color: #f5f5f5;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ margin-left: 2px;
+ margin-right: 8px;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+DIV.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px
+}
+
+DIV.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ margin-bottom: 6px;
+ font-weight: bold;
+}
+DIV.groupText {
+ margin-left: 16px;
+ font-style: italic;
+ font-size: 90%
+}
+/*BODY {
+ background: white;
+ color: black;
+ margin-right: 20px;
+ margin-left: 20px;
+}*/
+TD.indexkey {
+ background-color: #e8eef2;
+ font-weight: bold;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px;
+ border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+ background-color: #e8eef2;
+ font-style: italic;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px;
+ border: 1px solid #CCCCCC;
+}
+TR.memlist {
+ background-color: #f0f0f0;
+}
+P.formulaDsp {
+ text-align: center;
+}
+IMG.formulaDsp {
+}
+IMG.formulaInl {
+ vertical-align: middle;
+}
+SPAN.keyword { color: #008000 }
+SPAN.keywordtype { color: #604020 }
+SPAN.keywordflow { color: #e08000 }
+SPAN.comment { color: #800000 }
+SPAN.preprocessor { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral { color: #008080 }
+SPAN.vhdldigit { color: #ff00ff }
+SPAN.vhdlchar { color: #000000 }
+SPAN.vhdlkeyword { color: #700070 }
+SPAN.vhdllogic { color: #ff0000 }
+
+.mdescLeft {
+ padding: 0px 8px 4px 8px;
+ font-size: 80%;
+ font-style: italic;
+ background-color: #FAFAFA;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+}
+.mdescRight {
+ padding: 0px 8px 4px 8px;
+ font-size: 80%;
+ font-style: italic;
+ background-color: #FAFAFA;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+}
+.memItemLeft {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memItemRight {
+ padding: 1px 8px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memTemplItemLeft {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: none;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memTemplItemRight {
+ padding: 1px 8px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: none;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memTemplParams {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ color: #606060;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+FORM.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+INPUT.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+TD.tiny {
+ font-size: 75%;
+}
+a {
+ color: #1A41A8;
+}
+a:visited {
+ color: #2A3798;
+}
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #84b0c7;
+}
+TH.dirtab {
+ background: #e8eef2;
+ font-weight: bold;
+}
+HR {
+ height: 1px;
+ border: none;
+ border-top: 1px solid black;
+}
+
+/* Style for detailed member documentation */
+.memtemplate {
+ font-size: 80%;
+ color: #606060;
+ font-weight: normal;
+ margin-left: 3px;
+}
+.memnav {
+ background-color: #eeeeee;
+ border: 1px solid #dddddd;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+.memitem {
+ padding: 4px;
+ background-color: #eeeeee;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #dddddd;
+ -moz-border-radius: 4px 4px 4px 4px;
+}
+.memname {
+ white-space: nowrap;
+ font-weight: bold;
+ color: #ffffff;
+}
+.memdoc{
+ padding-left: 10px;
+}
+.memproto {
+ background-color: #111111;
+ width: 100%;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #000000;
+ font-weight: bold;
+ -moz-border-radius: 4px 4px 4px 4px;
+}
+.paramkey {
+ text-align: right;
+ color: #ffffff;
+}
+.paramtype {
+ white-space: nowrap;
+ color: #aaaaaa;
+}
+.paramname {
+ color: #ff0000;
+ font-style: italic;
+ white-space: nowrap;
+}
+/* End Styling for detailed member documentation */
+
+/* for the tree view */
+.ftvtree {
+ font-family: sans-serif;
+ margin:0.5em;
+}
+/* these are for tree view when used as main index */
+.directory {
+ font-size: 9pt;
+ font-weight: bold;
+}
+.directory h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+/* The following two styles can be used to replace the root node title */
+/* with an image of your choice. Simply uncomment the next two styles, */
+/* specify the name of your image and be sure to set 'height' to the */
+/* proper pixel height of your image. */
+
+/* .directory h3.swap { */
+/* height: 61px; */
+/* background-repeat: no-repeat; */
+/* background-image: url("yourimage.gif"); */
+/* } */
+/* .directory h3.swap span { */
+/* display: none; */
+/* } */
+
+.directory > h3 {
+ margin-top: 0;
+}
+.directory p {
+ margin: 0px;
+ white-space: nowrap;
+}
+.directory div {
+ display: none;
+ margin: 0px;
+}
+.directory img {
+ vertical-align: -30%;
+}
+/* these are for tree view when not used as main index */
+.directory-alt {
+ font-size: 100%;
+ font-weight: bold;
+}
+.directory-alt h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+.directory-alt > h3 {
+ margin-top: 0;
+}
+.directory-alt p {
+ margin: 0px;
+ white-space: nowrap;
+}
+.directory-alt div {
+ display: none;
+ margin: 0px;
+}
+.directory-alt img {
+ vertical-align: -30%;
+}
+
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-cocoa
+Description: E core library, Cocoa module
+@pkgconfig_requires_private@: @requirements_ecore_cocoa@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_cocoa
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-con
+Description: E core library, Con module
+@pkgconfig_requires_private@: @requirements_ecore_con@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_con
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-config
+Description: E core library, Config module
+@pkgconfig_requires_private@: @requirements_ecore_config@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_config
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-directfb
+Description: E core library, DirectFB module
+@pkgconfig_requires_private@: @requirements_ecore_directfb@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_directfb
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-evas
+Description: E core library, Evas module
+@pkgconfig_requires_private@: @requirements_ecore_evas@
+Version: @VERSION@
+Libs: -L${libdir} @ecore_evas_libs@
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-fb
+Description: E core library, FB module
+@pkgconfig_requires_private@: @requirements_ecore_fb@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_fb
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-file
+Description: E core library, File module
+@pkgconfig_requires_private@: @requirements_ecore_file@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_file
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-imf-evas
+Description: E core library, IMF Evas module
+@pkgconfig_requires_private@: @requirements_ecore_imf_evas@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_imf_evas
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-imf
+Description: E core library, IMF module
+@pkgconfig_requires_private@: @requirements_ecore_imf@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_imf
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-input-evas
+Description: E core library, Input module Evas extension
+@pkgconfig_requires_private@: @requirements_ecore_input_evas@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_input_evas
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-input
+Description: E core library, Input module
+@pkgconfig_requires_private@: @requirements_ecore_input@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_input
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-ipc
+Description: E core library, IPC module
+@pkgconfig_requires_private@: @requirements_ecore_ipc@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_ipc
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-job
+Description: E core library, Job module
+@pkgconfig_requires_private@: @requirements_ecore_job@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_job
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-sdl
+Description: E core library, SDL module
+@pkgconfig_requires_private@: @requirements_ecore_sdl@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_sdl
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-win32
+Description: E core library, Win32 module
+@pkgconfig_requires_private@: @requirements_ecore_win32@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_win32
+Libs.private: @ddraw_libs@ @direct3d_libs@
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-wince
+Description: E core library, WinCE module
+@pkgconfig_requires_private@: @requirements_ecore_wince@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_wince
+Libs.private: @WIN32_LIBS@
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-x
+Description: E core library, X module
+@pkgconfig_requires_private@: @requirements_ecore_x@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_x
+Libs.private: @x_libs@ @ecore_x_libs_private@
+Cflags: -I${includedir} @have_ecore_x_xcb_define@
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore
+Description: Ecore event abstraction library
+@pkgconfig_requires_private@: @requirements_ecore@
+Version: @VERSION@
+Libs: -L${libdir} -lecore
+Libs.private: -lm
+Cflags: -I${includedir}
--- /dev/null
+# Conditional build stuff; from rpm 4.4 /usr/lib/rpm/macros.
+# bcond_without defaults to WITH, and vice versa. Yes, it's
+# ass-backward. Blame PLD.
+# from KainX's changes to evas...
+%if %{!?with:1}0
+%define with() %{expand:%%{?with_%{1}:1}%%{!?with_%{1}:0}}
+%endif
+%if %{!?without:1}0
+%define without() %{expand:%%{?with_%{1}:0}%%{!?with_%{1}:1}}
+%endif
+%if %{!?bcond_with:1}0
+%define bcond_with() %{expand:%%{?_with_%{1}:%%global with_%{1} 1}}
+%endif
+%if %{!?bcond_without:1}0
+%define bcond_without() %{expand:%%{!?_without_%{1}:%%global with_%{1} 1}}
+%endif
+
+## disabled features
+%bcond_with lib_ecore_directfb
+%bcond_with lib_ecore_sdl
+
+## enabled features
+##%bcond_without module_engine_software_x11
+%bcond_without lib_ecore_fb
+%bcond_without lib_ecore_imf
+
+# This just keeps a missing doxygen from killing the build.
+%define _missing_doc_files_terminate_build 0
+
+%define breq_lib_ecore_directfb %{?with_lib_ecore_directfb:DirectFB}
+%define breq_lib_ecore_sdl %{?with_lib_ecore_sdl:SDL-devel}
+
+%define ac_with_lib_ecore_directfb --%{?with_lib_ecore_directfb:en}%{!?with_lib_ecore_directfb:dis}able-ecore-directfb
+%define ac_with_lib_ecore_fb --%{?with_lib_ecore_fb:en}%{!?with_lib_ecore_fb:dis}able-ecore-fb
+%define ac_with_lib_ecore_imf --%{?with_lib_ecore_imf:en}%{!?with_lib_ecore_imf:dis}able-ecore-imf
+%define ac_with_lib_ecore_sdl --%{?with_lib_ecore_sdl:en}%{!?with_lib_ecore_sdl:dis}able-ecore-sdl
+
+%{!?_rel:%{expand:%%global _rel 0.r%(svnversion | sed 's/[^0-9].*$//' || echo 0000)}}
+
+Summary: Enlightened Core X interface library
+Name: @PACKAGE@
+Version: @VERSION@
+Release: %{_rel}
+License: BSD
+Group: User Interface/X
+Source: %{name}-%{version}.tar.gz
+URL: http://www.enlightenment.org
+Packager: %{?_packager:%{_packager}}%{!?_packager:Michael Jennings <mej@eterm.org>}
+Vendor: %{?_vendorinfo:%{_vendorinfo}}%{!?_vendorinfo:The Enlightenment Project (http://www.enlightenment.org/)}
+Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}}
+#BuildSuggests: xorg-x11-devel, XFree86-devel, libX11-devel
+BuildRequires: libjpeg-devel, openssl-devel %{?breq_lib_ecore_directfb}
+BuildRequires: curl-devel, evas-devel, eet-devel %{?breq_lib_ecore_sdl}
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+
+%description
+Ecore is the event/X abstraction layer that makes doing selections,
+Xdnd, general X stuff, event loops, timeouts and idle handlers fast,
+optimized, and convenient. It's a separate library so anyone can make
+use of the work put into Ecore to make this job easy for applications.
+
+%package devel
+Summary: Ecore headers and development libraries.
+Group: Development/Libraries
+Requires: %{name} = %{version}
+Requires: curl-devel, openssl-devel, evas-devel, eet-devel
+Requires: ecore-con, ecore-evas, ecore-file, ecore-ipc
+Requires: ecore-x %{?with_lib_ecore_fb:ecore-fb} %{?with_lib_ecore_directfb:ecore-directfb}
+
+%description devel
+Ecore development files
+
+%package con
+Summary: Ecore Connection Library
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description con
+Ecore Connection Library
+
+%if %{with lib_ecore_directfb}
+%package directfb
+Summary: Ecore DirectFB system functions
+Group: Development/Libraries
+Requires: %{name} = %{version}
+%description directfb
+Ecore DirectFB system functions
+%endif
+
+%package evas
+Summary: Ecore Evas Wrapper Library
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description evas
+Ecore Evas Wrapper Library
+
+%if %{with lib_ecore_fb}
+%package fb
+Summary: Ecore frame buffer system functions
+Group: Development/Libraries
+Requires: %{name} = %{version}
+%description fb
+Ecore frame buffer system functions
+%endif
+
+%package file
+Summary: Ecore File Library
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description file
+Ecore File Library
+
+%if %{with lib_ecore_imf}
+%package imf
+Summary: Ecore IMF functions
+Group: Development/Libraries
+Requires: %{name} = %{version}
+%description imf
+Ecore IMF functions
+%endif
+
+%package input
+Summary: Ecore input functions
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description input
+Ecore input functions
+
+%package ipc
+Summary: Ecore inter-process communication functions
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description ipc
+Ecore inter-process communication functions
+
+%package x
+Summary: Ecore functions for dealing with the X Windows System
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description x
+Ecore functions for dealing with the X Windows System
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+CFLAGS="-I/usr/kerberos/include -I/usr/X11R6/include/X11/extensions"
+LDFLAGS="-L/usr/kerberos/lib -L/usr/X11R6/%{_lib}"
+export CFLAGS LDFLAGS
+%{configure} --prefix=%{_prefix} \
+ %{?ac_with_lib_ecore_directfb} \
+ %{?ac_with_lib_ecore_fb} \
+ %{?ac_with_lib_ecore_imf} \
+ %{?ac_with_lib_ecore_sdl}
+
+%{__make} %{?_smp_mflags} %{?mflags}
+
+%install
+%{__make} %{?mflags_install} DESTDIR=$RPM_BUILD_ROOT install
+%{find_lang} %{name}
+
+%post
+/sbin/ldconfig || :
+
+%postun
+/sbin/ldconfig || :
+
+%clean
+test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT
+
+%files -f %{name}.lang
+%defattr(-, root, root)
+%doc AUTHORS COPYING* README*
+%{_libdir}/libecore*.so.*
+
+%files devel
+%defattr(-, root, root)
+%doc doc/html
+%{_libdir}/*.so
+%{_libdir}/*.la
+%{_libdir}/*.a
+%{_libdir}/pkgconfig/*
+#%{_datadir}/aclocal/*
+%{_includedir}/*.h
+
+%files con
+%defattr(-, root, root)
+%{_libdir}/libecore_con*.so.*
+
+%if %{with lib_ecore_directfb}
+%files directfb
+%defattr(-, root, root)
+%{_libdir}/libecore_directfb*.so.*
+%endif
+
+%files evas
+%defattr(-, root, root)
+%{_libdir}/libecore_evas*.so.*
+
+%if %{with lib_ecore_fb}
+%files fb
+%defattr(-, root, root)
+%{_libdir}/libecore_fb*.so.*
+%endif
+
+%files file
+%defattr(-, root, root)
+%{_libdir}/libecore_file*.so.*
+
+%if %{with lib_ecore_imf}
+%files imf
+%defattr(-, root, root)
+%{_libdir}/libecore_imf*.so.*
+%endif
+
+%files input
+%defattr(-, root, root)
+%{_libdir}/libecore_input*.so.*
+
+%files ipc
+%defattr(-, root, root)
+%{_libdir}/libecore_ipc*.so.*
+
+%files x
+%defattr(-, root, root)
+%{_libdir}/libecore_x*.so.*
--- /dev/null
+# $Id: ecore.supp 11909 2004-10-19 16:40:25Z tsauerbeck $
+# valgrind suppression file for Ecore
+#
+{
+ BogusLeakError
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/X11R6/lib/libX11.so.6.2
+ fun:_XmbTextPropertyToTextList
+ fun:XmbTextPropertyToTextList
+}
+{
+ bogus2
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-2.3.3.so
+ fun:_X11TransWrite
+ obj:/usr/X11R6/lib/libX11.so.6.2
+ fun:_XReply
+}
+{
+ bogus3
+ Memcheck:Cond
+ obj:/usr/X11R6/lib/libX11.so.6.2
+ obj:/usr/X11R6/lib/libX11.so.6.2
+ obj:/usr/X11R6/lib/libX11.so.6.2
+ fun:_XlcCreateLocaleDataBase
+}
+{
+ bogus4
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-2.3.3.so
+ fun:_X11TransWrite
+ obj:/usr/X11R6/lib/libX11.so.6.2
+ fun:_XFlush
+}
+{
+ blah, blah, xlib sucks
+ Memcheck:Param
+ writev(vector[...])
+ obj:/lib/ld-2.3.3.so
+ obj:/usr/X11R6/lib/libX11.so.6.2
+ fun:_X11TransWritev
+ fun:_XSend
+}
--- /dev/null
+dnl AC_ABSTRACT_SOCKET_TEST(ACTION_IF_FOUND, ACTION_IF_NOT_FOUND)
+dnl test if a system supports the abstract socket namespace
+dnl by rephorm
+AC_DEFUN([AC_ABSTRACT_SOCKET_TEST], [
+AC_MSG_CHECKING(abstract sockets)
+AC_LANG_PUSH(C)
+AC_RUN_IFELSE([AC_LANG_PROGRAM(
+[[
+// headers
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+]],
+[[
+// main fn
+#define ABS_SUN_LEN(s, path) (strlen(path) + 1 + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
+ int fd;
+ struct sockaddr_un sock;
+ char *tmp;
+ char *name = "/ecore/dbus/abstract/test";
+
+ sock.sun_family = AF_UNIX;
+ snprintf(sock.sun_path, sizeof(sock.sun_path), ".%s", name);
+ sock.sun_path[0] = '\0';
+ fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (bind(fd, (struct sockaddr *)&sock, ABS_SUN_LEN(&sock, name)) < 0)
+ {
+ printf("Failed to bind to abstract socket.\n");
+ exit(1);
+ }
+
+ printf ("connected\n");
+ exit(0);
+]])],
+[$1],
+[$2])
+])
+
--- /dev/null
+dnl Copyright (C) 2004-2008 Kim Woelders
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+dnl That code is public domain and can be freely used or copied.
+dnl Originally snatched from somewhere...
+
+dnl Macro for checking if the compiler supports __attribute__
+
+dnl Usage: AC_C___ATTRIBUTE__
+dnl call AC_DEFINE for HAVE___ATTRIBUTE__ and __UNUSED__
+dnl if the compiler supports __attribute__, HAVE___ATTRIBUTE__ is
+dnl defined to 1 and __UNUSED__ is defined to __attribute__((unused))
+dnl otherwise, HAVE___ATTRIBUTE__ is not defined and __UNUSED__ is
+dnl defined to nothing.
+
+AC_DEFUN([AC_C___ATTRIBUTE__],
+[
+
+AC_MSG_CHECKING([for __attribute__])
+
+AC_CACHE_VAL([ac_cv___attribute__],
+ [AC_TRY_COMPILE(
+ [
+#include <stdlib.h>
+
+int func(int x);
+int foo(int x __attribute__ ((unused)))
+{
+ exit(1);
+}
+ ],
+ [],
+ [ac_cv___attribute__="yes"],
+ [ac_cv___attribute__="no"]
+ )])
+
+AC_MSG_RESULT($ac_cv___attribute__)
+
+if test "x${ac_cv___attribute__}" = "xyes" ; then
+ AC_DEFINE([HAVE___ATTRIBUTE__], [1], [Define to 1 if your compiler has __attribute__])
+ AC_DEFINE([__UNUSED__], [__attribute__((unused))], [Macro declaring a function argument to be unused])
+ else
+ AC_DEFINE([__UNUSED__], [], [Macro declaring a function argument to be unused])
+fi
+
+])
+
+dnl End of ac_attribute.m4
--- /dev/null
+dnl use: ECORE_CHECK_X_EXTENSION(Foo, header, lib, func, want)
+AC_DEFUN([ECORE_CHECK_X_EXTENSION],
+[
+pushdef([UP], translit([$1], [a-z], [A-Z]))dnl
+pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl
+
+UP[]_CFLAGS=""
+UP[]_LIBS=""
+use_[]DOWN="no"
+
+if test "x$5" != "xno"; then
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$x_cflags $x_includes"
+ AC_CHECK_HEADER(X11/extensions/$2,
+ [
+ AC_CHECK_LIB($3, $4,
+ [
+ AC_DEFINE(ECORE_[]UP, 1, [Build support for $1])
+ UP[]_LIBS="-l$3"
+ use_[]DOWN="yes"
+ ],
+ [ use_[]DOWN="no" ],
+ [ $x_libs ]
+ )
+ ],
+ [ use_[]DOWN="no" ],
+ [ #include <X11/Xlib.h> ]
+ )
+ CFLAGS=$SAVE_CFLAGS
+else
+ use_[]DOWN="no"
+ AC_MSG_NOTICE([$1 support disabled])
+fi
+
+AC_SUBST(UP[]_CFLAGS)
+AC_SUBST(UP[]_LIBS)
+
+popdef([UP])
+popdef([DOWN])
+])
--- /dev/null
+dnl use: ECORE_CHECK_MODULE(Foo, default-enabled, description[, dependancy[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]])
+AC_DEFUN([ECORE_CHECK_MODULE],
+[
+m4_pushdef([UP], m4_translit([[$1]], [-a-z], [_A-Z]))dnl
+m4_pushdef([DOWN], m4_translit([[$1]], [-A-Z], [_a-z]))dnl
+
+have_ecore_[]m4_defn([DOWN])=no
+ecore_[]m4_defn([DOWN])[]_cflags=
+ecore_[]m4_defn([DOWN])[]_libs=
+want_module=$2
+
+AC_ARG_ENABLE(ecore-$1,
+ [AC_HELP_STRING(
+ [--enable-ecore-$1],
+ [enable the ecore_]m4_defn([DOWN])[ module])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_module="yes"
+ else
+ want_module="no"
+ fi
+ ],
+ [])
+
+AC_MSG_CHECKING([whether Ecore_$3 module is to be built])
+
+if test "x${want_module}" = "xyes" ; then
+ if test "x$4" = "x" || test "x$4" = "xyes" ; then
+ AC_DEFINE([BUILD_ECORE_]m4_defn([UP]), [1], [Build Ecore_$3 Module])
+ have_ecore_[]m4_defn([DOWN])="yes"
+ ecore_[]m4_defn([DOWN])[]_libs="-lecore_[]m4_defn([DOWN])"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no (dependency failed)])
+ fi
+else
+ AC_MSG_RESULT([no])
+fi
+
+AM_CONDITIONAL([BUILD_ECORE_]UP, [test "x$have_ecore_]DOWN[" = "xyes"])
+
+AS_IF([test "x$have_ecore_[]m4_defn([DOWN])" = "xyes"], [$5], [$6])
+
+AC_SUBST(ecore_[]m4_defn([DOWN])[]_cflags)
+AC_SUBST(ecore_[]m4_defn([DOWN])[]_libs)
+
+m4_popdef([UP])
+m4_popdef([DOWN])
+])
+
+dnl use: ECORE_EVAS_CHECK_MODULE(foo-bar, want, description, backend[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_EVAS_CHECK_MODULE],
+[
+m4_pushdef([UP], m4_translit([[$1]], [-a-z], [_A-Z]))dnl
+m4_pushdef([DOWN], m4_translit([[$1]], [-A-Z], [_a-z]))dnl
+
+have_ecore_evas_[]m4_defn([DOWN])="no"
+want_module="$2"
+
+AC_ARG_ENABLE(ecore-evas-$1,
+ [AC_HELP_STRING(
+ [--enable-ecore-evas-$1],
+ [enable $3 support in the ecore_evas module.])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ want_module="yes"
+ else
+ want_module="no"
+ fi
+ ],
+ [])
+
+AC_MSG_CHECKING([whether ecore_evas $3 support is to be built])
+AC_MSG_RESULT([${want_module}])
+
+if test "x$4" = "xyes" -a \
+ "x$have_ecore_evas" = "xyes" -a \
+ "x$want_module" = "xyes" ; then
+ PKG_CHECK_EXISTS([evas-$1],
+ [
+ AC_DEFINE([BUILD_ECORE_EVAS_]m4_defn([UP]), [1], [Support for $3 Engine in Ecore_Evas])
+ have_ecore_evas_[]m4_defn([DOWN])="yes"
+ ])
+fi
+
+AC_MSG_CHECKING([whether ecore_evas $3 support is built])
+AC_MSG_RESULT([$have_ecore_evas_]m4_defn([DOWN]))
+
+AS_IF([test "x$have_ecore_evas_[]m4_defn([DOWN])" = "xyes"], [$5], [$6])
+
+m4_popdef([UP])
+m4_popdef([DOWN])
+])
--- /dev/null
+dnl use: ECORE_CHECK_POLL(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_POLL],
+[
+_ecore_want_poll=$1
+_ecore_have_poll="no"
+
+AC_ARG_ENABLE(poll,
+ [AC_HELP_STRING([--disable-poll], [disable poll in the ecore_file module])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_poll="yes"
+ else
+ _ecore_want_poll="no"
+ fi
+ ])
+
+AC_MSG_CHECKING(whether polling is to be used for filemonitoring)
+AC_MSG_RESULT(${_ecore_want_poll})
+
+if test "x${_ecore_want_poll}" = "xyes" ; then
+ AC_DEFINE([HAVE_POLL], [1], [ File monitoring with polling ])
+ _ecore_have_poll="yes"
+fi
+
+if test "x${_ecore_have_poll}" = "xyes" ; then
+ m4_default([$2], [:])
+else
+ m4_default([$3], [:])
+fi
+])
+
+dnl use: ECORE_CHECK_INOTIFY(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_INOTIFY],
+[
+_ecore_want_inotify=$1
+_ecore_have_inotify="no"
+
+dnl We need to check if the right inotify version is accessible
+_ecore_want_inotify="yes"
+AC_ARG_ENABLE(inotify,
+ [AC_HELP_STRING([--disable-inotify], [disable inotify in the ecore_file module])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_inotify="yes"
+ else
+ _ecore_want_inotify="no"
+ fi
+ ])
+
+AC_MSG_CHECKING(whether inotify is to be used for filemonitoring)
+AC_MSG_RESULT($_ecore_want_inotify)
+
+dnl It is hard to find a good test on how to check the correct
+dnl inotify version. They changed the headers a lot.
+dnl in kernel 2.6.13 __NR_inotify_init was added to the defined syscalls
+dnl in asm/unistd.h and IN_MOVE_SELF was added to linux/inotify.h
+dnl so with this check you need a very new kernel and kernel-headers!
+
+if test "x${_ecore_want_inotify}" = "xyes" ; then
+ AC_CHECK_LIB([c], [inotify_init],
+ [
+ AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ])
+ AC_DEFINE(HAVE_SYS_INOTIFY, 1, [ File monitoring with Inotify - sys/inotify.h ])
+ _ecore_have_inotify="yes"
+ ],
+ [
+ AC_TRY_COMPILE(
+ [
+ #include <asm/unistd.h>
+ #include <linux/inotify.h>
+ ],
+ [int a = __NR_inotify_init; int b = IN_MOVE_SELF;],
+ [
+ AC_DEFINE([HAVE_INOTIFY], [1], [ File monitoring with Inotify ])
+ _ecore_have_inotify="yes"
+ ],
+ [_ecore_have_inotify="no"])
+ ])
+fi
+
+if test "x$_ecore_have_inotify" = "xyes" ; then
+ m4_default([$2], [:])
+else
+ m4_default([$3], [:])
+fi
+])
+
+dnl use: ECORE_CHECK_NOTIFY_WIN32(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_NOTIFY_WIN32],
+[
+_ecore_want_notify_win32=$1
+_ecore_have_notify_win32="no"
+
+AC_ARG_ENABLE(notify-win32,
+ [AC_HELP_STRING([--disable-notify-win32], [disable Windows notification in the ecore_file module])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_notify_win32="yes"
+ else
+ _ecore_want_notify_win32="no"
+ fi
+ ])
+
+AC_MSG_CHECKING(whether Windows notification is to be used for filemonitoring)
+AC_MSG_RESULT(${_ecore_want_notify_win32})
+
+if test "x${_ecore_want_notify_win32}" = "xyes" ; then
+ AC_DEFINE([HAVE_NOTIFY_WIN32], [1], [ File monitoring with Windows notification ])
+ _ecore_have_notify_win32="yes"
+fi
+
+if test "x${_ecore_have_notify_win32}" = "xyes" ; then
+ m4_default([$2], [:])
+else
+ m4_default([$3], [:])
+fi
+])
+
+dnl use: ECORE_CHECK_CURL(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_CURL],
+[
+_ecore_want_curl=$1
+_ecore_have_curl="no"
+
+AC_ARG_ENABLE([curl],
+ [AC_HELP_STRING([--disable-curl], [disable curl support])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_curl="yes"
+ else
+ _ecore_want_curl="no"
+ fi
+ ])
+
+if test "x${_ecore_want_curl}" = "xyes" ; then
+ PKG_CHECK_MODULES(CURL, libcurl,
+ [
+ AC_DEFINE(HAVE_CURL, 1, [ Downloading with CURL ])
+ _ecore_have_curl="yes"
+ ],
+ [_ecore_have_curl="no"])
+fi
+
+if test "x$_ecore_have_curl" = "xyes" ; then
+ m4_default([$2], [:])
+else
+ m4_default([$3], [:])
+fi
+])
+
+dnl use: ECORE_CHECK_GNUTLS(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_GNUTLS],
+[
+_ecore_want_gnutls=$1
+_ecore_have_gnutls="no"
+
+AC_ARG_ENABLE([gnutls],
+ [AC_HELP_STRING([--disable-gnutls], [disable gnutls support])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_gnutls="yes"
+ else
+ _ecore_want_gnutls="no"
+ fi
+ ])
+
+if test "x${_ecore_want_gnutls}" = "xyes" -o "x${_ecore_want_gnutls}" = "xauto" ; then
+ PKG_CHECK_MODULES([TLS], [gnutls],
+ [
+ AC_DEFINE([USE_GNUTLS], [1], [Use GnuTLS])
+ _ecore_have_gnutls="yes"
+ ],
+ [_ecore_have_gnutls="no"])
+ # for ecore_con_ssl.c
+ PKG_CHECK_MODULES([TLS2], [gnutls >= 2.0.0],
+ [AC_DEFINE(USE_GNUTLS2, 1, [Use GnuTLS 2 or higher])],
+ [dummy="no"])
+fi
+
+if test "x$_ecore_have_gnutls" = "xyes" ; then
+ ifelse([$2], , :, [$2])
+else
+ ifelse([$3], , :, [$3])
+fi
+])
+
+dnl use: ECORE_CHECK_OPENSSL(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_OPENSSL],
+[
+_ecore_want_openssl=$1
+_ecore_have_openssl="no"
+
+AC_ARG_ENABLE(openssl,
+ [AC_HELP_STRING([--disable-openssl], [disable openssl support])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_openssl="yes"
+ else
+ _ecore_want_openssl="no"
+ fi
+ ])
+
+if test "x${_ecore_want_openssl}" = "xyes" -o "x${_ecore_want_openssl}" = "xauto"; then
+ PKG_CHECK_MODULES([SSL],
+ [openssl],
+ [
+ AC_DEFINE(USE_OPENSSL, 1, [Use OpenSSL])
+ _ecore_have_openssl="yes"
+ ],
+ [_ecore_have_openssl="no"])
+fi
+
+if test "x$_ecore_have_openssl" = "xyes" ; then
+ m4_default([$2], [:])
+else
+ m4_default([$3], [:])
+fi
+])
+
+dnl use: ECORE_CHECK_TSLIB(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_TSLIB],
+[
+_tslib_requirement=""
+_ecore_want_tslib=$1
+_ecore_have_tslib="no"
+TSLIB_LIBS=""
+TSLIB_CFLAGS=""
+
+AC_ARG_ENABLE([tslib],
+ [AC_HELP_STRING([--disable-tslib],
+ [disable the tslib support in ecore (currently ecore-fb).
+ @<:@default=detect@:>@])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_tslib="yes"
+ else
+ _ecore_want_tslib="no"
+ fi
+ ])
+
+if test "x${_ecore_want_tslib}" = "xyes" -o "x${_ecore_want_tslib}" = "xauto" ; then
+ PKG_CHECK_MODULES([TSLIB], [tslib-1.0],
+ [
+ AC_DEFINE(HAVE_TSLIB, 1, [Build Ecore_FB Touchscreen Code])
+ _ecore_have_tslib="yes"
+ _tslib_requirement="tslib-1.0"
+ ],[
+ PKG_CHECK_MODULES([TSLIB], [tslib],
+ [
+ AC_DEFINE(HAVE_TSLIB, 1, [Build Ecore_FB Touchscreen Code])
+ _ecore_have_tslib="yes"
+ _tslib_requirement="tslib"
+ ],[
+ AC_CHECK_HEADER([tslib.h],
+ [
+ AC_CHECK_LIB([ts], [ts_open],
+ [
+ TSLIB_LIBS="-lts"
+ TSLIB_CFLAGS=""
+ AC_DEFINE(HAVE_TSLIB, 1, [Build Ecore_FB Touchscreen Code])
+ _ecore_have_tslib="yes"
+ ],[
+ AC_CHECK_LIB([tslib], [ts_open],
+ [
+ TSLIB_LIBS="-ltslib"
+ TSLIB_CFLAGS=""
+ AC_DEFINE(HAVE_TSLIB, 1, [Build Ecore_FB Touchscreen Code])
+ _ecore_have_tslib="yes"
+ ],[
+ _ecore_have_tslib="no"
+ ])
+ ])
+ ])
+ ])
+ ])
+fi
+
+AC_SUBST(TSLIB_LIBS)
+AC_SUBST(TSLIB_CFLAGS)
+
+if test "x$_ecore_have_tslib" = "xyes" ; then
+ m4_default([$2], [:])
+else
+ m4_default([$3], [:])
+fi
+])
+
+dnl use: ECORE_CHECK_CARES(default-enabled[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_CHECK_CARES],
+[
+_ecore_want_cares=$1
+_ecore_have_cares="no"
+
+AC_ARG_ENABLE(cares,
+ [AC_HELP_STRING([--disable-cares], [disable cares support])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _ecore_want_cares="yes"
+ else
+ _ecore_want_cares="no"
+ fi
+ ])
+
+if test "x${_ecore_want_cares}" = "xyes" -o "x${_ecore_want_cares}" = "xauto" ; then
+ PKG_CHECK_MODULES([CARES], [libcares >= 1.6.1],
+ [_ecore_have_cares="yes"],
+ [_ecore_have_cares="no"])
+fi
+
+if test "x${_ecore_have_cares}" = "xyes" ; then
+ AC_DEFINE([HAVE_CARES], [1], [Build Ecore_Con_Info with c-ares support])
+fi
+
+if test "x$_ecore_have_cares" = "xyes" ; then
+ m4_default([$2], [:])
+else
+ m4_default([$3], [:])
+fi
+])
--- /dev/null
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+dnl That code is public domain and can be freely used or copied.
+
+dnl Macro that check if doxygen is available or not.
+
+dnl EFL_CHECK_DOXYGEN([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl Test for the doxygen program
+dnl Defines efl_doxygen
+dnl Defines the automake conditionnal EFL_BUILD_DOC
+dnl
+AC_DEFUN([EFL_CHECK_DOXYGEN],
+[
+
+dnl
+dnl Disable the build of the documentation
+dnl
+AC_ARG_ENABLE([doc],
+ [AC_HELP_STRING(
+ [--disable-doc],
+ [Disable documentation build @<:@default=enabled@:>@])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ efl_enable_doc="yes"
+ else
+ efl_enable_doc="no"
+ fi
+ ],
+ [efl_enable_doc="yes"])
+
+AC_MSG_CHECKING([whether to build documentation])
+AC_MSG_RESULT([${efl_enable_doc}])
+
+if test "x${efl_enable_doc}" = "xyes" ; then
+
+dnl Specify the file name, without path
+
+ efl_doxygen="doxygen"
+
+ AC_ARG_WITH([doxygen],
+ [AC_HELP_STRING(
+ [--with-doxygen=FILE],
+ [doxygen program to use @<:@default=doxygen@:>@])],
+
+dnl Check the given doxygen program.
+
+ [efl_doxygen=${withval}
+ AC_CHECK_PROG([efl_have_doxygen],
+ [${efl_doxygen}],
+ [yes],
+ [no])
+ if test "x${efl_have_doxygen}" = "xno" ; then
+ echo "WARNING:"
+ echo "The doxygen program you specified:"
+ echo "${efl_doxygen}"
+ echo "was not found. Please check the path and make sure "
+ echo "the program exists and is executable."
+ AC_MSG_WARN([no doxygen detected. Documentation will not be built])
+ fi
+ ],
+ [AC_CHECK_PROG([efl_have_doxygen],
+ [${efl_doxygen}],
+ [yes],
+ [no])
+ if test "x${efl_have_doxygen}" = "xno" ; then
+ echo "WARNING:"
+ echo "The doxygen program was not found in your execute path."
+ echo "You may have doxygen installed somewhere not covered by your path."
+ echo ""
+ echo "If this is the case make sure you have the packages installed, AND"
+ echo "that the doxygen program is in your execute path (see your"
+ echo "shell manual page on setting the \$PATH environment variable), OR"
+ echo "alternatively, specify the program to use with --with-doxygen."
+ AC_MSG_WARN([no doxygen detected. Documentation will not be built])
+ fi
+ ])
+fi
+
+dnl
+dnl Substitution
+dnl
+AC_SUBST([efl_doxygen])
+
+if ! test "x${efl_have_doxygen}" = "xyes" ; then
+ efl_enable_doc="no"
+fi
+
+AM_CONDITIONAL(EFL_BUILD_DOC, test "x${efl_enable_doc}" = "xyes")
+
+if test "x${efl_enable_doc}" = "xyes" ; then
+ m4_default([$1], [:])
+else
+ m4_default([$2], [:])
+fi
+
+])
+
+dnl End of efl_doxygen.m4
--- /dev/null
+dnl Check for PATH_MAX in limits.h, and define a default value if not found
+dnl This is a workaround for systems not providing PATH_MAX, like GNU/Hurd
+
+dnl EFL_CHECK_PATH_MAX([DEFAULT_VALUE_IF_NOT_FOUND])
+dnl
+dnl If PATH_MAX is not defined in <limits.h>, defines it
+dnl to DEFAULT_VALUE_IF_NOT_FOUND if it exists, or fallback
+dnl to using 4096
+
+AC_DEFUN([EFL_CHECK_PATH_MAX],
+[
+
+default_max=m4_default([$1], "4096")
+AC_LANG_PUSH([C])
+
+AC_MSG_CHECKING([for PATH_MAX in limits.h])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#include <limits.h>
+ ]],
+ [[
+int i = PATH_MAX;
+ ]])],
+ [AC_MSG_RESULT([yes])],
+ [
+ AC_DEFINE_UNQUOTED([PATH_MAX],
+ [${default_max}],
+ [default value since PATH_MAX is not defined])
+ AC_MSG_RESULT([no: using ${default_max}])
+ ])
+
+AC_LANG_POP([C])
+
+])
+dnl end of efl_path_max.m4
--- /dev/null
+dnl Copyright (C) 2010 Vincent Torri <vtorri at univ-evry dot fr>
+dnl That code is public domain and can be freely used or copied.
+
+dnl Macro that check if several pthread library is available or not.
+
+dnl Usage: EFL_CHECK_PTHREAD(want_pthread_spin[, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl Call AC_SUBST(EFL_PTHREAD_CFLAGS)
+dnl Call AC_SUBST(EFL_PTHREAD_LIBS)
+dnl Define EFL_HAVE_PTHREAD
+dnl Define EFL_HAVE_PTHREAD_SPINLOCK
+
+AC_DEFUN([EFL_CHECK_PTHREAD],
+[
+
+dnl configure option
+
+AC_ARG_ENABLE([pthread],
+ [AC_HELP_STRING([--disable-pthread], [enable POSIX threads code @<:@default=auto@:>@])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _efl_enable_pthread="yes"
+ else
+ _efl_enable_pthread="no"
+ fi
+ ],
+ [_efl_enable_pthread="auto"])
+
+AC_MSG_CHECKING([whether to build POSIX threads code])
+AC_MSG_RESULT([${_efl_enable_pthread}])
+
+dnl check if the compiler supports pthreads
+
+case "$host_os" in
+ mingw*)
+ _efl_pthread_cflags=""
+ _efl_pthread_libs="-lpthreadGC2"
+ ;;
+ solaris*)
+ _efl_pthread_cflags="-mt"
+ _efl_pthread_libs="-mt"
+ ;;
+ *)
+ _efl_pthread_cflags="-pthread"
+ _efl_pthread_libs="-pthread"
+ ;;
+esac
+
+_efl_have_pthread="no"
+
+if test "x${_efl_enable_pthread}" = "xyes" || test "x${_efl_enable_pthread}" = "xauto" ; then
+
+ SAVE_CFLAGS=${CFLAGS}
+ CFLAGS="${CFLAGS} ${_efl_pthread_cflags}"
+ SAVE_LDFLAGS=${LDFLAGS}
+ LDFLAGS="${LDFLAGS} ${_efl_pthread_libs}"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+#include <pthread.h>
+ ]],
+ [[
+pthread_t id;
+id = pthread_self();
+ ]])],
+ [_efl_have_pthread="yes"],
+ [_efl_have_pthread="no"])
+ CFLAGS=${SAVE_CFLAGS}
+ LDFLAGS=${SAVE_LDFLAGS}
+
+fi
+
+AC_MSG_CHECKING([whether system support POSIX threads])
+AC_MSG_RESULT([${_efl_have_pthread}])
+if test "$x{_efl_enable_pthread}" = "xyes" && test "x${_efl_have_pthread}" = "xno"; then
+ AC_MSG_ERROR([pthread support requested but not found.])
+fi
+
+EFL_PTHREAD_CFLAGS=""
+EFL_PTHREAD_LIBS=""
+if test "x${_efl_have_pthread}" = "xyes" ; then
+ EFL_PTHREAD_CFLAGS=${_efl_pthread_cflags}
+ EFL_PTHREAD_LIBS=${_efl_pthread_libs}
+fi
+
+AC_SUBST(EFL_PTHREAD_CFLAGS)
+AC_SUBST(EFL_PTHREAD_LIBS)
+
+if test "x${_efl_have_pthread}" = "xyes" ; then
+ AC_DEFINE(EFL_HAVE_PTHREAD, 1, [Define to mention that POSIX threads are supported])
+fi
+
+dnl check if the compiler supports pthreads spinlock
+
+_efl_have_pthread_spinlock="no"
+
+if test "x${_efl_have_pthread}" = "xyes" && test "x$1" = "xyes" ; then
+
+ SAVE_CFLAGS=${CFLAGS}
+ CFLAGS="${CFLAGS} ${EFL_PTHREAD_CFLAGS}"
+ SAVE_LDFLAGS=${LDFLAGS}
+ LDFLAGS="${LDFLAGS} ${EFL_PTHREAD_LIBS}"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+#include <pthread.h>
+ ]],
+ [[
+pthread_spinlock_t lock;
+int res;
+res = pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE);
+ ]])],
+ [_efl_have_pthread_spinlock="yes"],
+ [_efl_have_pthread_spinlock="no"])
+ CFLAGS=${SAVE_CFLAGS}
+ LDFLAGS=${SAVE_LDFLAGS}
+
+fi
+
+AC_MSG_CHECKING([whether to build POSIX threads spinlock code])
+AC_MSG_RESULT([${_efl_have_pthread_spinlock}])
+if test "x${_efl_enable_pthread}" = "xyes" && test "x${_efl_have_pthread_spinlock}" = "xno" && test "x$1" = "xyes" ; then
+ AC_MSG_WARN([pthread support requested but spinlocks are not supported])
+fi
+
+if test "x${_efl_have_pthread_spinlock}" = "xyes" ; then
+ AC_DEFINE(EFL_HAVE_PTHREAD_SPINLOCK, 1, [Define to mention that POSIX threads spinlocks are supported])
+fi
+
+AS_IF([test "x$_efl_have_pthread" = "xyes"], [$2], [$3])
+AS_IF([test "x$_efl_have_pthread_spinlock" = "xyes"], [$4], [$5])
+
+])
--- /dev/null
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+dnl That code is public domain and can be freely used or copied.
+
+dnl Macro that check if tests programs are wanted and if yes, if
+dnl the Check library is available.
+
+dnl Usage: EFL_CHECK_TESTS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl Define the automake conditionnal EFL_ENABLE_TESTS
+
+AC_DEFUN([EFL_CHECK_TESTS],
+[
+
+dnl configure option
+
+AC_ARG_ENABLE([tests],
+ [AC_HELP_STRING([--enable-tests], [enable tests @<:@default=disabled@:>@])],
+ [
+ if test "x${enableval}" = "xyes" ; then
+ _efl_enable_tests="yes"
+ else
+ _efl_enable_tests="no"
+ fi
+ ],
+ [_efl_enable_tests="no"])
+
+AC_MSG_CHECKING([whether tests are built])
+AC_MSG_RESULT([${_efl_enable_tests}])
+
+AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+
+if test "x${_efl_enable_tests}" = "xyes" ; then
+ PKG_CHECK_MODULES([CHECK],
+ [check >= 0.9.5],
+ [dummy="yes"],
+ [_efl_enable_tests="no"])
+fi
+
+AM_CONDITIONAL(EFL_ENABLE_TESTS, test "x${_efl_enable_tests}" = "xyes")
+
+AS_IF([test "x$_efl_enable_tests" = "xyes"], [$1], [$2])
+])
+
+dnl End of efl_tests.m4
--- /dev/null
+cs de el fr it
+
--- /dev/null
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = $(PACKAGE)
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --from-code=UTF-8 --foreign-user
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER = Enlightenment development team
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = enlightenment-devel@lists.sourceforge.net
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
--- /dev/null
+src/lib/ecore/ecore_getopt.c
--- /dev/null
+# ecore czech translation
+# quaker66@gmail.com
+msgid ""
+msgstr ""
+"Project-Id-Version: ecore\n"
+"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n"
+"POT-Creation-Date: 2010-03-08 09:04+0100\n"
+"PO-Revision-Date: 2009-10-27 19:35+0100\n"
+"Last-Translator: quaker66 <quaker66@gmail.com>\n"
+"Language-Team: cs <quaker66@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/lib/ecore/ecore_getopt.c:74
+msgid "Version:"
+msgstr "Verze:"
+
+#: src/lib/ecore/ecore_getopt.c:82
+msgid "Usage:"
+msgstr "Použití:"
+
+#: src/lib/ecore/ecore_getopt.c:87
+#, c-format
+msgid "%s [options]\n"
+msgstr "%s [volby]\n"
+
+#: src/lib/ecore/ecore_getopt.c:235
+msgid "Copyright:"
+msgstr "Copyright:"
+
+#: src/lib/ecore/ecore_getopt.c:246
+msgid "License:"
+msgstr "Licence:"
+
+#: src/lib/ecore/ecore_getopt.c:398
+msgid "Type: "
+msgstr "Typ: "
+
+#: src/lib/ecore/ecore_getopt.c:465
+msgid "Default: "
+msgstr "Výchozí: "
+
+#: src/lib/ecore/ecore_getopt.c:488
+msgid "Choices: "
+msgstr "Možnosti: "
+
+#: src/lib/ecore/ecore_getopt.c:585
+msgid "Options:\n"
+msgstr "Volby:\n"
+
+#: src/lib/ecore/ecore_getopt.c:704
+#, c-format
+msgid "ERROR: unknown option --%s.\n"
+msgstr "CHYBA: neznámá volba --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:706
+#, c-format
+msgid "ERROR: unknown option -%c.\n"
+msgstr "CHYBA: neznámá volba -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:762
+msgid "ERROR: "
+msgstr "CHYBA: "
+
+#: src/lib/ecore/ecore_getopt.c:839 src/lib/ecore/ecore_getopt.c:955
+#: src/lib/ecore/ecore_getopt.c:968 src/lib/ecore/ecore_getopt.c:980
+#: src/lib/ecore/ecore_getopt.c:994 src/lib/ecore/ecore_getopt.c:1038
+#: src/lib/ecore/ecore_getopt.c:1147 src/lib/ecore/ecore_getopt.c:1184
+msgid "value has no pointer set.\n"
+msgstr "hodnota nemá nastaven pointer.\n"
+
+#: src/lib/ecore/ecore_getopt.c:868 src/lib/ecore/ecore_getopt.c:1058
+#, c-format
+msgid "unknown boolean value %s.\n"
+msgstr "neznámá boolean hodnota %s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:912 src/lib/ecore/ecore_getopt.c:1138
+#, c-format
+msgid "invalid number format %s\n"
+msgstr "neznámý číselný formát %s\n"
+
+#: src/lib/ecore/ecore_getopt.c:1007
+#, c-format
+msgid "invalid choice \"%s\". Valid values are: "
+msgstr "neznámá volba \"%s\". Možné hodnoty jsou: "
+
+#: src/lib/ecore/ecore_getopt.c:1032
+msgid "missing parameter to append.\n"
+msgstr "chybějící parametr k připojení.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1128
+msgid "could not parse value.\n"
+msgstr "nemůžu parsovat hodnotu.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1177
+msgid "missing parameter.\n"
+msgstr "chybějící parametr.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1191
+msgid "missing callback function!\n"
+msgstr "chybějící callback funkce!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1214
+msgid "no version was defined.\n"
+msgstr "nebyla definována verze.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1228
+msgid "no copyright was defined.\n"
+msgstr "nebyl definován copyright.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1242
+msgid "no license was defined.\n"
+msgstr "nebyla definována licence.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1296
+#, c-format
+msgid "ERROR: unknown option --%s, ignored.\n"
+msgstr "CHYBA: neznámá volba --%s, ignoruji.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1329
+#, c-format
+msgid "ERROR: option --%s requires an argument!\n"
+msgstr "CHYBA: volba --%s vyžaduje argument!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1365
+#, c-format
+msgid "ERROR: unknown option -%c, ignored.\n"
+msgstr "CHYBA: neznámá volba -%c, ignoruji.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1403
+#, c-format
+msgid "ERROR: option -%c requires an argument!\n"
+msgstr "CHYBA: volba -%c vyžaduje argument!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1606
+msgid "ERROR: no parser provided.\n"
+msgstr "CHYBA: nebyl poskytnut parser.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1611
+msgid "ERROR: no values provided.\n"
+msgstr "CHYBA: nebyly poskytnuty hodnoty.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1620
+msgid "ERROR: no arguments provided.\n"
+msgstr "CHYBA: nebyly poskytnuty argumenty.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1646
+msgid "ERROR: invalid options found."
+msgstr "CHYBA: nalezeny neplatné volby."
+
+#: src/lib/ecore/ecore_getopt.c:1652
+#, c-format
+msgid " See --%s.\n"
+msgstr " viz. --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1654
+#, c-format
+msgid " See -%c.\n"
+msgstr " viz. -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1691
+#, c-format
+msgid "ERROR: incorrect geometry value '%s'\n"
+msgstr "CHYBA: neplatná hodnota geometrie '%s'\n"
+
+#: src/lib/ecore/ecore_getopt.c:1714
+#, c-format
+msgid "ERROR: incorrect size value '%s'\n"
+msgstr "CHYBA: neplatná hodnota velikosti '%s'\n"
--- /dev/null
+# Translation of ecore to German
+# Copyright (C) 2000 Carsten Haitzler and others.
+# This file is distributed under the same license as the ecore package.
+# Chris Leick <c.leick@vollbio.de>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ecore 0.9.9.063-2\n"
+"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n"
+"POT-Creation-Date: 2010-03-08 09:04+0100\n"
+"PO-Revision-Date: 2010-01-03 21:52+GMT\n"
+"Last-Translator: Chris Leick <c.leick@vollbio.de>\n"
+"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/lib/ecore/ecore_getopt.c:74
+msgid "Version:"
+msgstr "Version:"
+
+#: src/lib/ecore/ecore_getopt.c:82
+msgid "Usage:"
+msgstr "Aufruf:"
+
+#: src/lib/ecore/ecore_getopt.c:87
+#, c-format
+msgid "%s [options]\n"
+msgstr "%s [Optionen]\n"
+
+#: src/lib/ecore/ecore_getopt.c:235
+msgid "Copyright:"
+msgstr "Copyright:"
+
+#: src/lib/ecore/ecore_getopt.c:246
+msgid "License:"
+msgstr "Lizenz:"
+
+#: src/lib/ecore/ecore_getopt.c:398
+msgid "Type: "
+msgstr "Typ: "
+
+#: src/lib/ecore/ecore_getopt.c:465
+msgid "Default: "
+msgstr "Vorgabe: "
+
+#: src/lib/ecore/ecore_getopt.c:488
+msgid "Choices: "
+msgstr "Auswahlen: "
+
+#: src/lib/ecore/ecore_getopt.c:585
+msgid "Options:\n"
+msgstr "Optionen:\n"
+
+#: src/lib/ecore/ecore_getopt.c:704
+#, c-format
+msgid "ERROR: unknown option --%s.\n"
+msgstr "FEHLER: Unbekannte Option --%s\n"
+
+#: src/lib/ecore/ecore_getopt.c:706
+#, c-format
+msgid "ERROR: unknown option -%c.\n"
+msgstr "FEHLER: Unbekannte Option -%c\n"
+
+#: src/lib/ecore/ecore_getopt.c:762
+msgid "ERROR: "
+msgstr "FEHLER: "
+
+#: src/lib/ecore/ecore_getopt.c:839 src/lib/ecore/ecore_getopt.c:955
+#: src/lib/ecore/ecore_getopt.c:968 src/lib/ecore/ecore_getopt.c:980
+#: src/lib/ecore/ecore_getopt.c:994 src/lib/ecore/ecore_getopt.c:1038
+#: src/lib/ecore/ecore_getopt.c:1147 src/lib/ecore/ecore_getopt.c:1184
+msgid "value has no pointer set.\n"
+msgstr "kein Zeiger auf Wert gesetzt\n"
+
+#: src/lib/ecore/ecore_getopt.c:868 src/lib/ecore/ecore_getopt.c:1058
+#, c-format
+msgid "unknown boolean value %s.\n"
+msgstr "unbekannter boolescher Wert %s\n"
+
+#: src/lib/ecore/ecore_getopt.c:912 src/lib/ecore/ecore_getopt.c:1138
+#, c-format
+msgid "invalid number format %s\n"
+msgstr "ungültiges Zahlenformat %s\n"
+
+#: src/lib/ecore/ecore_getopt.c:1007
+#, c-format
+msgid "invalid choice \"%s\". Valid values are: "
+msgstr "ungültige Auswahl »%s«. Gültige Werte sind: "
+
+#: src/lib/ecore/ecore_getopt.c:1032
+msgid "missing parameter to append.\n"
+msgstr "fehlender Parameter zum Anhängen\n"
+
+#: src/lib/ecore/ecore_getopt.c:1128
+msgid "could not parse value.\n"
+msgstr "Wert kann nicht ausgewertet werden\n"
+
+#: src/lib/ecore/ecore_getopt.c:1177
+msgid "missing parameter.\n"
+msgstr "fehlender Parameter\n"
+
+#: src/lib/ecore/ecore_getopt.c:1191
+msgid "missing callback function!\n"
+msgstr "fehlende Rückruffunktion!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1214
+msgid "no version was defined.\n"
+msgstr "es wurde keine Version definiert.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1228
+msgid "no copyright was defined.\n"
+msgstr "es wurde kein Copyright definiert.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1242
+msgid "no license was defined.\n"
+msgstr "es wurde keine Lizenz definiert.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1296
+#, c-format
+msgid "ERROR: unknown option --%s, ignored.\n"
+msgstr "FEHLER: Unbekannte Option --%s, ignoriert\n"
+
+#: src/lib/ecore/ecore_getopt.c:1329
+#, c-format
+msgid "ERROR: option --%s requires an argument!\n"
+msgstr "FEHLER: Option --%s benötigt ein Argument!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1365
+#, c-format
+msgid "ERROR: unknown option -%c, ignored.\n"
+msgstr "FEHLER: Unbekannte Option -%c, ignoriert\n"
+
+#: src/lib/ecore/ecore_getopt.c:1403
+#, c-format
+msgid "ERROR: option -%c requires an argument!\n"
+msgstr "FEHLER: Option -%c benötigt ein Argument!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1606
+msgid "ERROR: no parser provided.\n"
+msgstr "FEHLER: Kein Parser bereitgestellt\n"
+
+#: src/lib/ecore/ecore_getopt.c:1611
+msgid "ERROR: no values provided.\n"
+msgstr "FEHLER: Keine Werte bereitgestellt\n"
+
+#: src/lib/ecore/ecore_getopt.c:1620
+msgid "ERROR: no arguments provided.\n"
+msgstr "FEHLER: Keine Argumente bereitgestellt\n"
+
+#: src/lib/ecore/ecore_getopt.c:1646
+msgid "ERROR: invalid options found."
+msgstr "FEHLER: Ungültige Optionen gefunden"
+
+#: src/lib/ecore/ecore_getopt.c:1652
+#, c-format
+msgid " See --%s.\n"
+msgstr " Siehe --%s\n"
+
+#: src/lib/ecore/ecore_getopt.c:1654
+#, c-format
+msgid " See -%c.\n"
+msgstr " Siehe -%c\n"
+
+#: src/lib/ecore/ecore_getopt.c:1691
+#, c-format
+msgid "ERROR: incorrect geometry value '%s'\n"
+msgstr "FEHLER: Falscher Geometriewert »%s«\n"
+
+#: src/lib/ecore/ecore_getopt.c:1714
+#, c-format
+msgid "ERROR: incorrect size value '%s'\n"
+msgstr "FEHLER: Falscher Größenwert »%s«\n"
--- /dev/null
+# Greek translation for Ecore.
+# This file is put in the public domain.
+# ragecryx <ragecryx@yahoo.gr>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Ecore\n"
+"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n"
+"POT-Creation-Date: 2010-03-08 09:04+0100\n"
+"PO-Revision-Date: 2009-12-15 00:56+0200\n"
+"Last-Translator: Giorgos Koutsikos <ragecryx@yahoo.gr>\n"
+"Language-Team: Greek\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/lib/ecore/ecore_getopt.c:74
+msgid "Version:"
+msgstr "Έκδοση:"
+
+#: src/lib/ecore/ecore_getopt.c:82
+msgid "Usage:"
+msgstr "Χρήση:"
+
+#: src/lib/ecore/ecore_getopt.c:87
+#, c-format
+msgid "%s [options]\n"
+msgstr "%s [επιλογές]\n"
+
+#: src/lib/ecore/ecore_getopt.c:235
+msgid "Copyright:"
+msgstr "Πνευματικά δικαιώματα:"
+
+#: src/lib/ecore/ecore_getopt.c:246
+msgid "License:"
+msgstr "Άδεια:"
+
+#: src/lib/ecore/ecore_getopt.c:398
+msgid "Type: "
+msgstr "Τύπος:"
+
+#: src/lib/ecore/ecore_getopt.c:465
+msgid "Default: "
+msgstr "Προκαθορισμένο:"
+
+#: src/lib/ecore/ecore_getopt.c:488
+msgid "Choices: "
+msgstr "Επιλογές:"
+
+#: src/lib/ecore/ecore_getopt.c:585
+msgid "Options:\n"
+msgstr "Επιλογές:\n"
+
+#: src/lib/ecore/ecore_getopt.c:704
+#, c-format
+msgid "ERROR: unknown option --%s.\n"
+msgstr "ΣΦΑΛΜΑ: άγνωστη παράμετρος --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:706
+#, c-format
+msgid "ERROR: unknown option -%c.\n"
+msgstr "ΣΦΑΛΜΑ: άγνωστη παράμετρος -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:762
+msgid "ERROR: "
+msgstr "ΣΦΑΛΜΑ:"
+
+#: src/lib/ecore/ecore_getopt.c:839 src/lib/ecore/ecore_getopt.c:955
+#: src/lib/ecore/ecore_getopt.c:968 src/lib/ecore/ecore_getopt.c:980
+#: src/lib/ecore/ecore_getopt.c:994 src/lib/ecore/ecore_getopt.c:1038
+#: src/lib/ecore/ecore_getopt.c:1147 src/lib/ecore/ecore_getopt.c:1184
+msgid "value has no pointer set.\n"
+msgstr "η τιμή δεν έχει δείκτη ορισμένο.\n"
+
+#: src/lib/ecore/ecore_getopt.c:868 src/lib/ecore/ecore_getopt.c:1058
+#, c-format
+msgid "unknown boolean value %s.\n"
+msgstr "άγνωστη τιμή boolean %s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:912 src/lib/ecore/ecore_getopt.c:1138
+#, c-format
+msgid "invalid number format %s\n"
+msgstr "άγνωστη μορφή αριθμού %s\n"
+
+#: src/lib/ecore/ecore_getopt.c:1007
+#, c-format
+msgid "invalid choice \"%s\". Valid values are: "
+msgstr "μη-έγκυρη επιλογή \"%s\". Οι τιμές είναι: "
+
+#: src/lib/ecore/ecore_getopt.c:1032
+msgid "missing parameter to append.\n"
+msgstr "ελλιπής παράμετρος προς επισύναψη.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1128
+msgid "could not parse value.\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1177
+msgid "missing parameter.\n"
+msgstr "ελλιπής παράμετρος.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1191
+msgid "missing callback function!\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1214
+msgid "no version was defined.\n"
+msgstr "δεν έχει οριστεί έκδοση.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1228
+msgid "no copyright was defined.\n"
+msgstr "δεν έχουν οριστεί πνευματικά δικαιώματα.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1242
+msgid "no license was defined.\n"
+msgstr "δεν έχει οριστεί άδεια.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1296
+#, c-format
+msgid "ERROR: unknown option --%s, ignored.\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1329
+#, c-format
+msgid "ERROR: option --%s requires an argument!\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1365
+#, c-format
+msgid "ERROR: unknown option -%c, ignored.\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1403
+#, c-format
+msgid "ERROR: option -%c requires an argument!\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1606
+msgid "ERROR: no parser provided.\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1611
+msgid "ERROR: no values provided.\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1620
+msgid "ERROR: no arguments provided.\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1646
+msgid "ERROR: invalid options found."
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1652
+#, c-format
+msgid " See --%s.\n"
+msgstr " Δες --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1654
+#, c-format
+msgid " See -%c.\n"
+msgstr " Δες -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1691
+#, c-format
+msgid "ERROR: incorrect geometry value '%s'\n"
+msgstr ""
+
+#: src/lib/ecore/ecore_getopt.c:1714
+#, c-format
+msgid "ERROR: incorrect size value '%s'\n"
+msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ " "
+#~ msgstr ""
+#~ "\n"
+#~ " "
+
+#~ msgid "true"
+#~ msgstr "true"
+
+#~ msgid "false"
+#~ msgstr "false"
+
+#~ msgid "f"
+#~ msgstr "f"
+
+#~ msgid "no"
+#~ msgstr "no"
+
+#~ msgid "off"
+#~ msgstr "off"
+
+#~ msgid "t"
+#~ msgstr "t"
+
+#~ msgid "yes"
+#~ msgstr "yes"
+
+#~ msgid "on"
+#~ msgstr "on"
--- /dev/null
+# French translation for Ecore.
+# This file is put in the public domain.
+# batden <batden@orange.fr>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Ecore\n"
+"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n"
+"POT-Creation-Date: 2010-03-08 09:04+0100\n"
+"PO-Revision-Date: 2010-03-13 14:04+0400\n"
+"Last-Translator: batden <batden@orange.fr>\n"
+"Language-Team: Enlightenment French Team <pourunmondesansgourou@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: FRANCE\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: src/lib/ecore/ecore_getopt.c:74
+msgid "Version:"
+msgstr "Version :"
+
+#: src/lib/ecore/ecore_getopt.c:82
+msgid "Usage:"
+msgstr "Usage :"
+
+#: src/lib/ecore/ecore_getopt.c:87
+#, c-format
+msgid "%s [options]\n"
+msgstr "%s [options]\n"
+
+#: src/lib/ecore/ecore_getopt.c:235
+msgid "Copyright:"
+msgstr "Copyright :"
+
+#: src/lib/ecore/ecore_getopt.c:246
+msgid "License:"
+msgstr "Licence :"
+
+#: src/lib/ecore/ecore_getopt.c:398
+msgid "Type: "
+msgstr "Type : "
+
+#: src/lib/ecore/ecore_getopt.c:465
+msgid "Default: "
+msgstr "Par défaut :"
+
+#: src/lib/ecore/ecore_getopt.c:488
+msgid "Choices: "
+msgstr "Choix :"
+
+#: src/lib/ecore/ecore_getopt.c:585
+msgid "Options:\n"
+msgstr "Options :\n"
+
+#: src/lib/ecore/ecore_getopt.c:704
+#, c-format
+msgid "ERROR: unknown option --%s.\n"
+msgstr "ERREUR : option inconnue --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:706
+#, c-format
+msgid "ERROR: unknown option -%c.\n"
+msgstr "ERREUR : option inconnue -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:762
+msgid "ERROR: "
+msgstr "ERREUR :"
+
+#: src/lib/ecore/ecore_getopt.c:839
+#: src/lib/ecore/ecore_getopt.c:955
+#: src/lib/ecore/ecore_getopt.c:968
+#: src/lib/ecore/ecore_getopt.c:980
+#: src/lib/ecore/ecore_getopt.c:994
+#: src/lib/ecore/ecore_getopt.c:1038
+#: src/lib/ecore/ecore_getopt.c:1147
+#: src/lib/ecore/ecore_getopt.c:1184
+msgid "value has no pointer set.\n"
+msgstr "la valeur n'a aucun pointeur défini.\n"
+
+#: src/lib/ecore/ecore_getopt.c:868
+#: src/lib/ecore/ecore_getopt.c:1058
+#, c-format
+msgid "unknown boolean value %s.\n"
+msgstr "valeur booléenne inconnue %s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:912
+#: src/lib/ecore/ecore_getopt.c:1138
+#, c-format
+msgid "invalid number format %s\n"
+msgstr "format du nombre non valide %s\n"
+
+#: src/lib/ecore/ecore_getopt.c:1007
+#, c-format
+msgid "invalid choice \"%s\". Valid values are: "
+msgstr "choix non valide \"%s\". Les valeurs valides sont : "
+
+#: src/lib/ecore/ecore_getopt.c:1032
+msgid "missing parameter to append.\n"
+msgstr "paramètre manquant à ajouter.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1128
+msgid "could not parse value.\n"
+msgstr "analyse de la valeur impossible.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1177
+msgid "missing parameter.\n"
+msgstr "paramètre manquant.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1191
+msgid "missing callback function!\n"
+msgstr "fonction de rappel manquante !\n"
+
+#: src/lib/ecore/ecore_getopt.c:1214
+msgid "no version was defined.\n"
+msgstr "aucune version n'est définie.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1228
+msgid "no copyright was defined.\n"
+msgstr "aucun copyright n'est défini.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1242
+msgid "no license was defined.\n"
+msgstr "aucune licence n'est définie.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1296
+#, c-format
+msgid "ERROR: unknown option --%s, ignored.\n"
+msgstr "ERREUR : option inconnue --%s, non prise en compte.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1329
+#, c-format
+msgid "ERROR: option --%s requires an argument!\n"
+msgstr "ERREUR : l'option --%s requiert un argument !\n"
+
+#: src/lib/ecore/ecore_getopt.c:1365
+#, c-format
+msgid "ERROR: unknown option -%c, ignored.\n"
+msgstr "ERREUR : option inconnue -%c, non prise en compte.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1403
+#, c-format
+msgid "ERROR: option -%c requires an argument!\n"
+msgstr "ERREUR : l'option -%c requiert un argument !\n"
+
+#: src/lib/ecore/ecore_getopt.c:1606
+msgid "ERROR: no parser provided.\n"
+msgstr "ERREUR : aucun analyseur n'est fourni.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1611
+msgid "ERROR: no values provided.\n"
+msgstr "ERREUR : aucune valeur n'est fournie.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1620
+msgid "ERROR: no arguments provided.\n"
+msgstr "ERREUR : aucun argument n'est fourni.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1646
+msgid "ERROR: invalid options found."
+msgstr "ERREUR : options non valides détectées."
+
+#: src/lib/ecore/ecore_getopt.c:1652
+#, c-format
+msgid " See --%s.\n"
+msgstr " Voir --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1654
+#, c-format
+msgid " See -%c.\n"
+msgstr " Voir -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1691
+#, c-format
+msgid "ERROR: incorrect geometry value '%s'\n"
+msgstr "ERREUR : valeur géométrique incorrecte '%s'\n"
+
+#: src/lib/ecore/ecore_getopt.c:1714
+#, c-format
+msgid "ERROR: incorrect size value '%s'\n"
+msgstr "ERREUR : valeur de taille incorrecte '%s'\n"
+
+#~ msgid ""
+#~ "\n"
+#~ " "
+#~ msgstr ""
+#~ "\n"
+#~ " "
+#~ msgid "true"
+#~ msgstr "true"
+#~ msgid "false"
+#~ msgstr "false"
+#~ msgid "f"
+#~ msgstr "f"
+#~ msgid "no"
+#~ msgstr "no"
+#~ msgid "off"
+#~ msgstr "off"
+#~ msgid "t"
+#~ msgstr "t"
+#~ msgid "yes"
+#~ msgstr "yes"
+#~ msgid "on"
+#~ msgstr "on"
+
--- /dev/null
+# Italian translation for Ecore.
+# This file is put in the public domain.
+# Massimo Maiurana <maiurana@gmail.com>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Ecore\n"
+"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n"
+"POT-Creation-Date: 2010-03-08 09:04+0100\n"
+"PO-Revision-Date: 2009-10-27 19:36+0100\n"
+"Last-Translator: quaker66 <quaker66@gmail.com>\n"
+"Language-Team: none\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/lib/ecore/ecore_getopt.c:74
+msgid "Version:"
+msgstr "Versione:"
+
+#: src/lib/ecore/ecore_getopt.c:82
+msgid "Usage:"
+msgstr "Uso:"
+
+#: src/lib/ecore/ecore_getopt.c:87
+#, c-format
+msgid "%s [options]\n"
+msgstr "%s [opzioni]\n"
+
+#: src/lib/ecore/ecore_getopt.c:235
+msgid "Copyright:"
+msgstr "Copyright:"
+
+#: src/lib/ecore/ecore_getopt.c:246
+msgid "License:"
+msgstr "Licenza:"
+
+#: src/lib/ecore/ecore_getopt.c:398
+msgid "Type: "
+msgstr "Tipo: "
+
+#: src/lib/ecore/ecore_getopt.c:465
+msgid "Default: "
+msgstr "Predefinito:"
+
+#: src/lib/ecore/ecore_getopt.c:488
+msgid "Choices: "
+msgstr "Scelte:"
+
+#: src/lib/ecore/ecore_getopt.c:585
+msgid "Options:\n"
+msgstr "Opzioni:\n"
+
+#: src/lib/ecore/ecore_getopt.c:704
+#, c-format
+msgid "ERROR: unknown option --%s.\n"
+msgstr "ERRORE: opzione sconosciuta --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:706
+#, c-format
+msgid "ERROR: unknown option -%c.\n"
+msgstr "ERRORE: opzione sconosciuta -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:762
+msgid "ERROR: "
+msgstr "ERRORE:"
+
+#: src/lib/ecore/ecore_getopt.c:839 src/lib/ecore/ecore_getopt.c:955
+#: src/lib/ecore/ecore_getopt.c:968 src/lib/ecore/ecore_getopt.c:980
+#: src/lib/ecore/ecore_getopt.c:994 src/lib/ecore/ecore_getopt.c:1038
+#: src/lib/ecore/ecore_getopt.c:1147 src/lib/ecore/ecore_getopt.c:1184
+msgid "value has no pointer set.\n"
+msgstr "il valore non ha puntatori impostati.\n"
+
+#: src/lib/ecore/ecore_getopt.c:868 src/lib/ecore/ecore_getopt.c:1058
+#, c-format
+msgid "unknown boolean value %s.\n"
+msgstr "valore booleano sconosciuto %s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:912 src/lib/ecore/ecore_getopt.c:1138
+#, c-format
+msgid "invalid number format %s\n"
+msgstr "formato numero non valido %s\n"
+
+#: src/lib/ecore/ecore_getopt.c:1007
+#, c-format
+msgid "invalid choice \"%s\". Valid values are: "
+msgstr "scelta non valida \"%s\". I valori ammessi sono: "
+
+#: src/lib/ecore/ecore_getopt.c:1032
+msgid "missing parameter to append.\n"
+msgstr "parametro da appendere mancante.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1128
+msgid "could not parse value.\n"
+msgstr "impossibile il parsing del valore.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1177
+msgid "missing parameter.\n"
+msgstr "parametro mancante.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1191
+msgid "missing callback function!\n"
+msgstr "funzione callback mancante!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1214
+msgid "no version was defined.\n"
+msgstr "nessuna versione definita.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1228
+msgid "no copyright was defined.\n"
+msgstr "nessun copyright definito.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1242
+msgid "no license was defined.\n"
+msgstr "nessuna licenza definita.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1296
+#, c-format
+msgid "ERROR: unknown option --%s, ignored.\n"
+msgstr "ERRORE: opzione sconosciuta --%s, ignorata.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1329
+#, c-format
+msgid "ERROR: option --%s requires an argument!\n"
+msgstr "ERRORE: l'opzione --%s richiede un argomento!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1365
+#, c-format
+msgid "ERROR: unknown option -%c, ignored.\n"
+msgstr "ERRORE: opzione sconosciuta -%c, ignorata.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1403
+#, c-format
+msgid "ERROR: option -%c requires an argument!\n"
+msgstr "ERRORE: l'opzione -%c richiede un argomento!\n"
+
+#: src/lib/ecore/ecore_getopt.c:1606
+msgid "ERROR: no parser provided.\n"
+msgstr "ERRORE: nessun parser fornito.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1611
+msgid "ERROR: no values provided.\n"
+msgstr "ERRORE: nessun valore fornito.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1620
+msgid "ERROR: no arguments provided.\n"
+msgstr "ERRORE: nessun argomento fornito.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1646
+msgid "ERROR: invalid options found."
+msgstr "ERRORE: trovate opzioni non valide."
+
+#: src/lib/ecore/ecore_getopt.c:1652
+#, c-format
+msgid " See --%s.\n"
+msgstr " Vedere --%s.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1654
+#, c-format
+msgid " See -%c.\n"
+msgstr " Vedere -%c.\n"
+
+#: src/lib/ecore/ecore_getopt.c:1691
+#, c-format
+msgid "ERROR: incorrect geometry value '%s'\n"
+msgstr "ERRORE: valore geometrico non corretto '%s'\n"
+
+#: src/lib/ecore/ecore_getopt.c:1714
+#, c-format
+msgid "ERROR: incorrect size value '%s'\n"
+msgstr "ERRORE: valore dimensione non corretto '%s'\n"
+
+#~ msgid ""
+#~ "\n"
+#~ " "
+#~ msgstr ""
+#~ "\n"
+#~ " "
+
+#~ msgid "true"
+#~ msgstr "vero"
+
+#~ msgid "false"
+#~ msgstr "falso"
+
+#~ msgid "f"
+#~ msgstr "f"
+
+#~ msgid "no"
+#~ msgstr "no"
+
+#~ msgid "off"
+#~ msgstr "off"
+
+#~ msgid "t"
+#~ msgstr "t"
+
+#~ msgid "yes"
+#~ msgstr "sì"
+
+#~ msgid "on"
+#~ msgstr "on"
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS = lib bin tests
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+ecore_config
+ecore_evas_test
+ecore_test
+ecore_dbus_test
+ecore_dbus_hal_test
+ecore_dbus_receiver_test
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_CONFIG
+ECORE_CONFIG_PROG = ecore_config
+ECORE_CONFIG_LIB = $(top_builddir)/src/lib/ecore_config/libecore_config.la
+else
+ECORE_CONFIG_PROG =
+ECORE_CONFIG_LIB =
+endif
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_config \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_config \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@EINA_CFLAGS@ \
+@EET_CFLAGS@
+
+bin_PROGRAMS = $(ECORE_CONFIG_PROG)
+
+ecore_config_SOURCES = \
+ecore_config.c
+
+ecore_config_LDADD = \
+$(ECORE_CONFIG_LIB) \
+$(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+ecore_config_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(ECORE_CONFIG_LIB)
--- /dev/null
+#include "config.h"
+#include "Ecore.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef BUILD_ECORE_CONFIG
+#include <unistd.h>
+#include <getopt.h>
+#include <Eet.h>
+#include "Ecore_Config.h"
+#include "ecore_config_private.h"
+
+// strcmp for paths - for sorting folders before files
+static int
+pathcmp(const char *s1, const char *s2)
+{
+ char *s1d, *s2d;
+
+ // strip common part of paths
+ while(*s1 && *s2 && *s1 == *s2)
+ {
+ s1++;
+ s2++;
+ }
+
+ // handle /foo/bar/baz <> /foo/bar_baz properly
+ if (*s1 == '/' && *s2 != '/') return -1;
+ if (*s1 != '/' && *s2 == '/') return 1;
+
+ // skip leading /
+ if (*s1 == '/') s1++;
+ if (*s2 == '/') s2++;
+
+ // order folders before files
+ s1d = strchr(s1, '/');
+ s2d = strchr(s2, '/');
+ if (s1d != NULL && s2d == NULL) return -1;
+ if (s1d == NULL && s2d != NULL) return 1;
+
+ return strcmp(s1, s2);
+}
+
+static int
+del(const char *key)
+{
+ Ecore_Config_Prop *e;
+ e = ecore_config_get(key);
+ if(e == NULL) return -1;
+
+ ecore_config_dst(e);
+ return 0;
+}
+
+static int
+get(const char *key)
+{
+ Ecore_Config_Prop *e;
+ char *temp = NULL;
+
+ if (!(e = ecore_config_get(key)))
+ {
+ EINA_LOG_ERR("No such property");
+ return -1;
+ }
+
+ printf("%-10s", ecore_config_type_get(e));
+
+ switch (e->type)
+ {
+ case ECORE_CONFIG_NIL:
+ printf("\n");
+ break;
+ case ECORE_CONFIG_INT:
+ printf("%ld\n", ecore_config_int_get(key));
+ break;
+ case ECORE_CONFIG_BLN:
+ printf("%d\n", ecore_config_boolean_get(key));
+ break;
+ case ECORE_CONFIG_FLT:
+ printf("%lf\n", ecore_config_float_get(key));
+ break;
+ case ECORE_CONFIG_STR:
+ temp = ecore_config_string_get(key);
+ break;
+ case ECORE_CONFIG_RGB:
+ temp = ecore_config_argbstr_get(key);
+ break;
+ case ECORE_CONFIG_THM:
+ temp = ecore_config_theme_get(key);
+ break;
+ default:
+ EINA_LOG_ERR("Property has unrecognized type");
+ return -1;
+ }
+ if(temp)
+ {
+ printf("\"%s\"\n", temp);
+ free(temp);
+ }
+ return 0;
+}
+
+static int
+list(const char *file)
+{
+ Ecore_Config_Prop *e;
+ Eina_List *keys = NULL;
+ char *key;
+
+ e = __ecore_config_bundle_local->data;
+
+ do
+ {
+ // don't show system settings
+ if( !(e->flags & ECORE_CONFIG_FLAG_SYSTEM) )
+ keys = eina_list_append(keys, e->key);
+ }
+ while((e = e->next));
+ keys = eina_list_sort(keys, -1, EINA_COMPARE_CB(pathcmp));
+
+ EINA_LIST_FREE(keys, key)
+ {
+ printf("%-28s\t", key);
+ get(key);
+ }
+
+ return 0;
+}
+
+static void
+usage_and_exit(const char *prog, int ret, const char *msg)
+{
+ if (msg) fprintf(stderr, "%s\n\n", msg);
+ fprintf(stderr, "Usage: %s <options> <command>\n", prog);
+ fprintf(stderr, "Modify ecore_config files\n\n");
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -c, --file=FILE config file\n");
+ fprintf(stderr, " -k, --key=KEY must be given for all commands except -a\n\n");
+ fprintf(stderr, "Commands:\n");
+ fprintf(stderr, " -a, --list get all keys\n");
+ fprintf(stderr, " -g, --get get key\n");
+ fprintf(stderr, " -d, --del delete key\n");
+ fprintf(stderr, " -b, --bool=VALUE set boolean\n");
+ fprintf(stderr, " -f, --float=VALUE set float\n");
+ fprintf(stderr, " -i, --int=VALUE set integer\n");
+ fprintf(stderr, " -r, --rgb=VALUE set RGBA\n");
+ fprintf(stderr, " -s, --string=VALUE set string\n");
+ fprintf(stderr, " -t, --theme=VALUE set theme\n\n");
+ exit(ret);
+}
+
+int
+main(int argc, char * const argv[])
+{
+ char *prog, *file, *key;
+ void *value = (void *)NULL;
+ char cmd = 's';
+ int type = -1;
+ int ret = 0;
+ long i;
+ float f;
+
+ file = key = prog = NULL;
+ eina_init();
+ prog = strdup(argv[0]);
+
+ if(argc < 4)
+ usage_and_exit(prog, 2, NULL);
+
+ while(1)
+ {
+ static struct option long_options[] = {
+ {"file", 1, 0, 'c'},
+ {"list", 0, 0, 'a'},
+ {"get", 0, 0, 'g'},
+ {"del", 0, 0, 'd'},
+ {"bool", 1, 0, 'b'},
+ {"float", 1, 0, 'f'},
+ {"int", 1, 0, 'i'},
+ {"rgb", 1, 0, 'r'},
+ {"string", 1, 0, 's'},
+ {"theme", 1, 0, 't'},
+ {"key", 1, 0, 'k'},
+ {0, 0, 0, 0}
+ };
+
+ ret = getopt_long(argc, argv, "c:agdb:f:i:r:s:t:k:", long_options, NULL);
+ if(ret == -1)
+ break;
+
+ switch(ret)
+ {
+ case 'k':
+ key = strdup(optarg);
+ break;
+ case 'n':
+ if(value)
+ usage_and_exit(prog, 2, "too many commands");
+ type = ECORE_CONFIG_NIL;
+ value = NULL;
+ break;
+ case 'b':
+ if(value)
+ usage_and_exit(prog, 2, "too many commands");
+ type = ECORE_CONFIG_BLN;
+ i = atoi(optarg);
+ value = &i;
+ break;
+ case 'i':
+ if(value)
+ usage_and_exit(prog, 2, "too many commands");
+ type = ECORE_CONFIG_INT;
+ i = atoi(optarg);
+ value = &i;
+ break;
+ case 'f':
+ if(value)
+ usage_and_exit(prog, 2, "too many commands");
+ type = ECORE_CONFIG_FLT;
+ f = atof(optarg);
+ value = &f;
+ break;
+ case 'r':
+ if(value)
+ usage_and_exit(prog, 2, "too many commands");
+ type = ECORE_CONFIG_RGB;
+ i = (long) strtoul( (*optarg == '#') ? (optarg + 1) : optarg, NULL, 16 );
+ value = &i;
+ break;
+ case 's':
+ if(value)
+ usage_and_exit(prog, 2, "too many commands");
+ type = ECORE_CONFIG_STR;
+ value = strdup(optarg);
+ break;
+ case 't':
+ if(value)
+ usage_and_exit(prog, 2, "too many commands");
+ type = ECORE_CONFIG_THM;
+ value = strdup(optarg);
+ break;
+ case 'c':
+ if(file)
+ free(file);
+ file = strdup(optarg);
+ break;
+ case '?':
+ case ':':
+ return 1;
+ default:
+ cmd = ret;
+ break;
+ }
+ }
+
+ if(cmd == 's' && type == -1)
+ usage_and_exit(prog, 2, "You need to specify a command!");
+
+ if(cmd != 'a' && key == NULL)
+ usage_and_exit(prog, 2, "You need to specify key!");
+
+ if(ecore_config_init("econfig") != ECORE_CONFIG_ERR_SUCC)
+ {
+ EINA_LOG_ERR("Couldn't init ecore_config!");
+ return 1;
+ }
+
+ // Load configuration from file
+ ecore_config_file_load(file);
+
+ ret = 0;
+
+ // Execute command
+ switch (cmd)
+ {
+ case 's':
+ if (ecore_config_typed_set(key, value, type) != ECORE_CONFIG_ERR_SUCC)
+ {
+ fprintf(stderr, "Set failed for %s", key);
+ ret = 1;
+ } else {
+ ecore_config_file_save(file);
+ }
+ get(key); // display value after setting it
+ break;
+ case 'd':
+ if(del(key))
+ {
+ fprintf(stderr, "Delete failed for %s", key);
+ ret = 1;
+ } else {
+ ecore_config_file_save(file);
+ }
+ break;
+ case 'g':
+ if (get(key)) ret = 1;
+ break;
+ case 'a':
+ if (list(file)) ret = 1;
+ break;
+ default:
+ EINA_LOG_ERR("Unhandled command '%c'", cmd);
+ }
+
+ ecore_config_shutdown();
+
+ if(type == ECORE_CONFIG_STR || type == ECORE_CONFIG_THM)
+ free(value);
+
+ if(file)
+ free(file);
+ eina_shutdown();
+ return ret;
+}
+#else
+int
+main(int argc, const char **argv)
+{
+ printf("Ecore_config module not compiled. This program is empty.\n");
+ return -1;
+}
+#endif
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+## Process this file with automake to produce Makefile.in
+MAINTAINERCLEANFILES = Makefile.in
+SUBDIRS = \
+ecore \
+ecore_input \
+ecore_input_evas \
+ecore_fb \
+ecore_directfb \
+ecore_con \
+ecore_x \
+ecore_win32 \
+ecore_wince \
+ecore_sdl \
+ecore_cocoa \
+ecore_ipc \
+ecore_evas \
+ecore_config \
+ecore_file \
+ecore_imf \
+ecore_imf_evas
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore.la
--- /dev/null
+#ifndef _ECORE_H
+#define _ECORE_H
+
+#ifdef _MSC_VER
+# include <Evil.h>
+#endif
+
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+/**
+ * @file Ecore.h
+ * @brief The file that provides the program utility, main loop and timer
+ * functions.
+ *
+ * This header provides the Ecore event handling loop. For more
+ * details, see @ref Ecore_Main_Loop_Group.
+ *
+ * For the main loop to be of any use, you need to be able to add events
+ * and event handlers. Events for file descriptor events are covered in
+ * @ref Ecore_FD_Handler_Group.
+ *
+ * Time functions are covered in @ref Ecore_Time_Group.
+ *
+ * There is also provision for callbacks for when the loop enters or
+ * exits an idle state. See @ref Idle_Group for more information.
+ *
+ * Functions are also provided for spawning child processes using fork.
+ * See @ref Ecore_Exe_Basic_Group and @ref Ecore_Exe_Signal_Group for
+ * more details.
+ */
+
+#ifdef _WIN32
+# include <winsock2.h>
+#elif (defined (__FreeBSD__) && (__FreeBSD_version >= 420001)) || defined (__OpenBSD__)
+# include <sys/select.h>
+# include <signal.h>
+#else
+# include <sys/time.h>
+# include <signal.h>
+#endif
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ECORE_CALLBACK_CANCEL 0 /**< Return value to remove a callback */
+#define ECORE_CALLBACK_RENEW 1 /**< Return value to keep a callback */
+
+#define ECORE_EVENT_NONE 0
+#define ECORE_EVENT_SIGNAL_USER 1 /**< User signal event */
+#define ECORE_EVENT_SIGNAL_HUP 2 /**< Hup signal event */
+#define ECORE_EVENT_SIGNAL_EXIT 3 /**< Exit signal event */
+#define ECORE_EVENT_SIGNAL_POWER 4 /**< Power signal event */
+#define ECORE_EVENT_SIGNAL_REALTIME 5 /**< Realtime signal event */
+#define ECORE_EVENT_COUNT 6
+
+#define ECORE_EXE_PRIORITY_INHERIT 9999
+
+ EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */
+ EAPI extern int ECORE_EXE_EVENT_DEL; /**< A child process has been deleted (it exited, naming consistant with the rest of ecore). */
+ EAPI extern int ECORE_EXE_EVENT_DATA; /**< Data from a child process. */
+ EAPI extern int ECORE_EXE_EVENT_ERROR; /**< Errors from a child process. */
+
+ enum _Ecore_Fd_Handler_Flags
+ {
+ ECORE_FD_READ = 1, /**< Fd Read mask */
+ ECORE_FD_WRITE = 2, /**< Fd Write mask */
+ ECORE_FD_ERROR = 4 /**< Fd Error mask */
+ };
+ typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
+
+ enum _Ecore_Exe_Flags /* flags for executing a child with its stdin and/or stdout piped back */
+ {
+ ECORE_EXE_PIPE_READ = 1, /**< Exe Pipe Read mask */
+ ECORE_EXE_PIPE_WRITE = 2, /**< Exe Pipe Write mask */
+ ECORE_EXE_PIPE_ERROR = 4, /**< Exe Pipe error mask */
+ ECORE_EXE_PIPE_READ_LINE_BUFFERED = 8, /**< Reads are buffered until a newline and delivered 1 event per line */
+ ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, /**< Errors are buffered until a newline and delivered 1 event per line */
+ ECORE_EXE_PIPE_AUTO = 32, /**< stdout and stderr are buffered automatically */
+ ECORE_EXE_RESPAWN = 64, /**< FIXME: Exe is restarted if it dies */
+ ECORE_EXE_USE_SH = 128, /**< Use /bin/sh to run the command. */
+ ECORE_EXE_NOT_LEADER = 256 /**< Do not use setsid() to have the executed process be its own session leader */
+ };
+ typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags;
+
+ enum _Ecore_Exe_Win32_Priority
+ {
+ ECORE_EXE_WIN32_PRIORITY_IDLE, /**< Idle priority, for monitoring the system */
+ ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL, /**< Below default priority */
+ ECORE_EXE_WIN32_PRIORITY_NORMAL, /**< Default priority */
+ ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL, /**< Above default priority */
+ ECORE_EXE_WIN32_PRIORITY_HIGH, /**< High priority, use with care as other threads in the system will not get processor time */
+ ECORE_EXE_WIN32_PRIORITY_REALTIME /**< Realtime priority, should be almost never used as it can interrupt system threads that manage mouse input, keyboard input, and background disk flushing */
+ };
+ typedef enum _Ecore_Exe_Win32_Priority Ecore_Exe_Win32_Priority;
+
+ enum _Ecore_Poller_Type /* Poller types */
+ {
+ ECORE_POLLER_CORE = 0 /**< The core poller interval */
+ };
+ typedef enum _Ecore_Poller_Type Ecore_Poller_Type;
+
+ typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */
+ typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */
+ typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */
+ typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; /**< A handle for idle enterers */
+ typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; /**< A handle for idle exiters */
+ typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for Fd handlers */
+ typedef struct _Ecore_Win32_Handler Ecore_Win32_Handler; /**< A handle for HANDLE handlers on Windows */
+ typedef struct _Ecore_Event_Handler Ecore_Event_Handler; /**< A handle for an event handler */
+ typedef struct _Ecore_Event_Filter Ecore_Event_Filter; /**< A handle for an event filter */
+ typedef struct _Ecore_Event Ecore_Event; /**< A handle for an event */
+ typedef struct _Ecore_Animator Ecore_Animator; /**< A handle for animators */
+ typedef struct _Ecore_Pipe Ecore_Pipe; /**< A handle for pipes */
+ typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */
+ typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */
+ typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */
+ typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */
+ typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */
+ typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< Realtime signal event */
+ typedef struct _Ecore_Exe_Event_Add Ecore_Exe_Event_Add; /**< Spawned Exe add event */
+ typedef struct _Ecore_Exe_Event_Del Ecore_Exe_Event_Del; /**< Spawned Exe exit event */
+ typedef struct _Ecore_Exe_Event_Data_Line Ecore_Exe_Event_Data_Line; /**< Lines from a child process */
+ typedef struct _Ecore_Exe_Event_Data Ecore_Exe_Event_Data; /**< Data from a child process */
+ typedef struct _Ecore_Thread Ecore_Thread;
+
+ typedef struct _Ecore_Job Ecore_Job; /**< A job handle */
+
+ struct _Ecore_Event_Signal_User /** User signal event */
+ {
+ int number; /**< The signal number. Either 1 or 2 */
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef _WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Hup /** Hup signal event */
+ {
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef _WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Exit /** Exit request event */
+ {
+ unsigned int interrupt : 1; /**< Set if the exit request was an interrupt signal*/
+ unsigned int quit : 1; /**< set if the exit request was a quit signal */
+ unsigned int terminate : 1; /**< Set if the exit request was a terminate singal */
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef _WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Power /** Power event */
+ {
+ void *ext_data; /**< Extension data - not used */
+
+#ifndef _WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Event_Signal_Realtime /** Realtime event */
+ {
+ int num; /**< The realtime signal's number */
+
+#ifndef _WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Exe_Event_Add /** Process add event */
+ {
+ Ecore_Exe *exe; /**< The handle to the added process */
+ void *ext_data; /**< Extension data - not used */
+ };
+
+ struct _Ecore_Exe_Event_Del /** Process exit event */
+ {
+ pid_t pid; /**< The process ID of the process that exited */
+ int exit_code; /**< The exit code of the process */
+ Ecore_Exe *exe; /**< The handle to the exited process, or NULL if not found */
+ int exit_signal; /** < The signal that caused the process to exit */
+ unsigned int exited : 1; /** < set to 1 if the process exited of its own accord */
+ unsigned int signalled : 1; /** < set to 1 id the process exited due to uncaught signal */
+ void *ext_data; /**< Extension data - not used */
+#ifndef _WIN32
+ siginfo_t data; /**< Signal info */
+#endif
+ };
+
+ struct _Ecore_Exe_Event_Data_Line /**< Lines from a child process */
+ {
+ char *line;
+ int size;
+ };
+
+ struct _Ecore_Exe_Event_Data /** Data from a child process event */
+ {
+ Ecore_Exe *exe; /**< The handle to the process */
+ void *data; /**< the raw binary data from the child process that was recieved */
+ int size; /**< the size of this data in bytes */
+ Ecore_Exe_Event_Data_Line *lines; /**< an array of line data if line buffered, the last one has it's line member set to NULL */
+ };
+
+ EAPI int ecore_init(void);
+ EAPI int ecore_shutdown(void);
+
+ EAPI void ecore_app_args_set(int argc, const char **argv);
+ EAPI void ecore_app_args_get(int *argc, char ***argv);
+ EAPI void ecore_app_restart(void);
+
+ EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data);
+ EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler);
+ EAPI Ecore_Event *ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data);
+ EAPI void *ecore_event_del(Ecore_Event *event);
+ EAPI int ecore_event_type_new(void);
+ EAPI Ecore_Event_Filter *ecore_event_filter_add(void * (*func_start) (void *data), int (*func_filter) (void *data, void *loop_data, int type, void *event), void (*func_end) (void *data, void *loop_data), const void *data);
+ EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef);
+ EAPI int ecore_event_current_type_get(void);
+ EAPI void *ecore_event_current_event_get(void);
+
+
+ EAPI void ecore_exe_run_priority_set(int pri);
+ EAPI int ecore_exe_run_priority_get(void);
+ EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data);
+ EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data);
+ EAPI void ecore_exe_callback_pre_free_set(Ecore_Exe *exe, void (*func)(void *data, const Ecore_Exe *exe));
+ EAPI Eina_Bool ecore_exe_send(Ecore_Exe *exe, const void *data, int size);
+ EAPI void ecore_exe_close_stdin(Ecore_Exe *exe);
+ EAPI void ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int start_lines, int end_lines);
+ EAPI Ecore_Exe_Event_Data *ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags);
+ EAPI void ecore_exe_event_data_free(Ecore_Exe_Event_Data *data);
+ EAPI void *ecore_exe_free(Ecore_Exe *exe);
+ EAPI pid_t ecore_exe_pid_get(const Ecore_Exe *exe);
+ EAPI void ecore_exe_tag_set(Ecore_Exe *exe, const char *tag);
+ EAPI const char *ecore_exe_tag_get(const Ecore_Exe *exe);
+ EAPI const char *ecore_exe_cmd_get(const Ecore_Exe *exe);
+ EAPI void *ecore_exe_data_get(const Ecore_Exe *exe);
+ EAPI Ecore_Exe_Flags ecore_exe_flags_get(const Ecore_Exe *exe);
+ EAPI void ecore_exe_pause(Ecore_Exe *exe);
+ EAPI void ecore_exe_continue(Ecore_Exe *exe);
+ EAPI void ecore_exe_interrupt(Ecore_Exe *exe);
+ EAPI void ecore_exe_quit(Ecore_Exe *exe);
+ EAPI void ecore_exe_terminate(Ecore_Exe *exe);
+ EAPI void ecore_exe_kill(Ecore_Exe *exe);
+ EAPI void ecore_exe_signal(Ecore_Exe *exe, int num);
+ EAPI void ecore_exe_hup(Ecore_Exe *exe);
+
+ EAPI Ecore_Idler *ecore_idler_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_idler_del(Ecore_Idler *idler);
+
+ EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(int (*func) (void *data), const void *data);
+ EAPI Ecore_Idle_Enterer *ecore_idle_enterer_before_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
+
+ EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
+
+ EAPI void ecore_main_loop_iterate(void);
+
+ EAPI void ecore_main_loop_select_func_set(int (*func)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout));
+ EAPI void *ecore_main_loop_select_func_get(void);
+
+ EAPI Eina_Bool ecore_main_loop_glib_integrate(void);
+ EAPI void ecore_main_loop_glib_always_integrate_disable(void);
+
+ EAPI void ecore_main_loop_begin(void);
+ EAPI void ecore_main_loop_quit(void);
+ EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data, int (*buf_func) (void *buf_data, Ecore_Fd_Handler *fd_handler), const void *buf_data);
+ EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, void (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data);
+ EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
+ EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler);
+ EAPI int ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
+ EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
+
+ EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, int (*func) (void *data, Ecore_Win32_Handler *wh), const void *data);
+ EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler);
+
+ EAPI Ecore_Pipe *ecore_pipe_add(void (*handler) (void *data, void *buffer, unsigned int nbyte), const void *data);
+ EAPI void *ecore_pipe_del(Ecore_Pipe *p);
+ EAPI int ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes);
+ EAPI void ecore_pipe_write_close(Ecore_Pipe *p);
+ EAPI void ecore_pipe_read_close(Ecore_Pipe *p);
+
+ EAPI Ecore_Thread *ecore_thread_run(void (*func_heavy)(void *data), void (*func_end)(void *data), void (*func_cancel)(void *data), const void *data);
+ EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread);
+
+ EAPI double ecore_time_get(void);
+ EAPI double ecore_loop_time_get(void);
+
+ EAPI Ecore_Timer *ecore_timer_add(double in, int (*func) (void *data), const void *data);
+ EAPI Ecore_Timer *ecore_timer_loop_add(double in, int (*func) (void *data), const void *data);
+ EAPI void *ecore_timer_del(Ecore_Timer *timer);
+ EAPI void ecore_timer_interval_set(Ecore_Timer *timer, double in);
+ EAPI double ecore_timer_interval_get(Ecore_Timer *timer);
+ EAPI void ecore_timer_freeze(Ecore_Timer *timer);
+ EAPI void ecore_timer_thaw(Ecore_Timer *timer);
+ EAPI void ecore_timer_delay(Ecore_Timer *timer, double add);
+ EAPI double ecore_timer_pending_get(Ecore_Timer *timer);
+
+ EAPI double ecore_timer_precision_get(void);
+ EAPI void ecore_timer_precision_set(double precision);
+
+ EAPI Ecore_Animator *ecore_animator_add(int (*func) (void *data), const void *data);
+ EAPI void *ecore_animator_del(Ecore_Animator *animator);
+ EAPI void ecore_animator_freeze(Ecore_Animator *animator);
+ EAPI void ecore_animator_thaw(Ecore_Animator *animator);
+ EAPI void ecore_animator_frametime_set(double frametime);
+ EAPI double ecore_animator_frametime_get(void);
+
+ EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, double poll_time);
+ EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type);
+ EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, int (*func) (void *data), const void *data);
+ EAPI void *ecore_poller_del(Ecore_Poller *poller);
+
+ EAPI Ecore_Job *ecore_job_add(void (*func) (void *data), const void *data);
+ EAPI void *ecore_job_del(Ecore_Job *job);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
+#ifndef _ECORE_GETOPT_H
+#define _ECORE_GETOPT_H
+
+#include <stdio.h>
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+/**
+ * @file Ecore_Getopt.h
+ * @brief Contains powerful getopt replacement.
+ *
+ * This replacement handles both short (-X) or long options (--ABC)
+ * options, with various actions supported, like storing one value and
+ * already converting to required type, counting number of
+ * occurrences, setting true or false values, show help, license,
+ * copyright and even support user-defined callbacks.
+ *
+ * It is provided a set of C Pre Processor macros so definition is
+ * straightforward.
+ *
+ * Values will be stored elsewhere indicated by an array of pointers
+ * to values, it is given in separate to parser description so you can
+ * use multiple values with the same parser.
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef enum {
+ ECORE_GETOPT_ACTION_STORE,
+ ECORE_GETOPT_ACTION_STORE_CONST,
+ ECORE_GETOPT_ACTION_STORE_TRUE,
+ ECORE_GETOPT_ACTION_STORE_FALSE,
+ ECORE_GETOPT_ACTION_CHOICE,
+ ECORE_GETOPT_ACTION_APPEND,
+ ECORE_GETOPT_ACTION_COUNT,
+ ECORE_GETOPT_ACTION_CALLBACK,
+ ECORE_GETOPT_ACTION_HELP,
+ ECORE_GETOPT_ACTION_VERSION,
+ ECORE_GETOPT_ACTION_COPYRIGHT,
+ ECORE_GETOPT_ACTION_LICENSE
+ } Ecore_Getopt_Action;
+
+ typedef enum {
+ ECORE_GETOPT_TYPE_STR,
+ ECORE_GETOPT_TYPE_BOOL,
+ ECORE_GETOPT_TYPE_SHORT,
+ ECORE_GETOPT_TYPE_INT,
+ ECORE_GETOPT_TYPE_LONG,
+ ECORE_GETOPT_TYPE_USHORT,
+ ECORE_GETOPT_TYPE_UINT,
+ ECORE_GETOPT_TYPE_ULONG,
+ ECORE_GETOPT_TYPE_DOUBLE
+ } Ecore_Getopt_Type;
+
+ typedef enum {
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO = 0,
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES = 1,
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL = 3
+ } Ecore_Getopt_Desc_Arg_Requirement;
+
+ typedef union _Ecore_Getopt_Value Ecore_Getopt_Value;
+
+ typedef struct _Ecore_Getopt_Desc_Store Ecore_Getopt_Desc_Store;
+ typedef struct _Ecore_Getopt_Desc_Callback Ecore_Getopt_Desc_Callback;
+ typedef struct _Ecore_Getopt_Desc Ecore_Getopt_Desc;
+ typedef struct _Ecore_Getopt Ecore_Getopt;
+
+ union _Ecore_Getopt_Value
+ {
+ char **strp;
+ unsigned char *boolp;
+ short *shortp;
+ int *intp;
+ long *longp;
+ unsigned short *ushortp;
+ unsigned int *uintp;
+ unsigned long *ulongp;
+ double *doublep;
+ Eina_List **listp;
+ void **ptrp;
+ };
+
+ struct _Ecore_Getopt_Desc_Store
+ {
+ Ecore_Getopt_Type type; /**< type of data being handled */
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ union
+ {
+ const char *strv;
+ unsigned char boolv;
+ short shortv;
+ int intv;
+ long longv;
+ unsigned short ushortv;
+ unsigned int uintv;
+ unsigned long ulongv;
+ double doublev;
+ } def;
+ };
+
+ struct _Ecore_Getopt_Desc_Callback
+ {
+ unsigned char (*func)(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
+ const void *data;
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ const char *def;
+ };
+
+ struct _Ecore_Getopt_Desc
+ {
+ char shortname; /**< used with a single dash */
+ const char *longname; /**< used with double dashes */
+ const char *help; /**< used by --help/ecore_getopt_help() */
+ const char *metavar; /**< used by ecore_getopt_help() with nargs > 0 */
+
+ Ecore_Getopt_Action action; /**< define how to handle it */
+ union
+ {
+ const Ecore_Getopt_Desc_Store store;
+ const void *store_const;
+ const char *const *choices; /* NULL terminated. */
+ const Ecore_Getopt_Type append_type;
+ const Ecore_Getopt_Desc_Callback callback;
+ const void *dummy;
+ } action_param;
+ };
+
+ struct _Ecore_Getopt
+ {
+ const char *prog; /**< to be used when ecore_app_args_get() fails */
+ const char *usage; /**< usage example, %prog is replaced */
+ const char *version; /**< if exists, --version will work */
+ const char *copyright; /**< if exists, --copyright will work */
+ const char *license; /**< if exists, --license will work */
+ const char *description; /**< long description, possible multiline */
+ unsigned char strict : 1; /**< fail on errors */
+ const Ecore_Getopt_Desc descs[]; /* NULL terminated. */
+ };
+
+#define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE, \
+ {.store = {type, arg_requirement, default_value}}}
+
+#define ECORE_GETOPT_STORE(shortname, longname, help, type) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
+
+#define ECORE_GETOPT_STORE_STR(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_STR)
+#define ECORE_GETOPT_STORE_BOOL(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_BOOL)
+#define ECORE_GETOPT_STORE_SHORT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_SHORT)
+#define ECORE_GETOPT_STORE_INT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_INT)
+#define ECORE_GETOPT_STORE_LONG(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_LONG)
+#define ECORE_GETOPT_STORE_USHORT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_USHORT)
+#define ECORE_GETOPT_STORE_UINT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_UINT)
+#define ECORE_GETOPT_STORE_ULONG(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_ULONG)
+#define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_DOUBLE)
+
+
+#define ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, type) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
+
+#define ECORE_GETOPT_STORE_METAVAR_STR(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_STR)
+#define ECORE_GETOPT_STORE_METAVAR_BOOL(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_BOOL)
+#define ECORE_GETOPT_STORE_METAVAR_SHORT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_SHORT)
+#define ECORE_GETOPT_STORE_METAVAR_INT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_INT)
+#define ECORE_GETOPT_STORE_METAVAR_LONG(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_LONG)
+#define ECORE_GETOPT_STORE_METAVAR_USHORT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_USHORT)
+#define ECORE_GETOPT_STORE_METAVAR_UINT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_UINT)
+#define ECORE_GETOPT_STORE_METAVAR_ULONG(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_ULONG)
+#define ECORE_GETOPT_STORE_METAVAR_DOUBLE(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_DOUBLE)
+
+
+#define ECORE_GETOPT_STORE_DEF(shortname, longname, help, type, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL, \
+ default_value)
+
+#define ECORE_GETOPT_STORE_DEF_STR(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_STR, \
+ {.strv = default_value})
+#define ECORE_GETOPT_STORE_DEF_BOOL(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_BOOL, \
+ {.boolv = default_value})
+#define ECORE_GETOPT_STORE_DEF_SHORT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_SHORT, \
+ {.shortv = default_value})
+#define ECORE_GETOPT_STORE_DEF_INT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_INT, \
+ {.intv = default_value})
+#define ECORE_GETOPT_STORE_DEF_LONG(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_LONG, \
+ {.longv = default_value})
+#define ECORE_GETOPT_STORE_DEF_USHORT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_USHORT, \
+ {.ushortv = default_value})
+#define ECORE_GETOPT_STORE_DEF_UINT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_UINT, \
+ {.uintv, default_value})
+#define ECORE_GETOPT_STORE_DEF_ULONG(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_ULONG, \
+ {.ulongv = default_value})
+#define ECORE_GETOPT_STORE_DEF_DOUBLE(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_DOUBLE, \
+ {.doublev = default_value})
+
+#define ECORE_GETOPT_STORE_FULL_STR(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_STR, \
+ arg_requirement, \
+ {.strv = default_value})
+#define ECORE_GETOPT_STORE_FULL_BOOL(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_BOOL, \
+ arg_requirement, \
+ {.boolv = default_value})
+#define ECORE_GETOPT_STORE_FULL_SHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_SHORT, \
+ arg_requirement, \
+ {.shortv = default_value})
+#define ECORE_GETOPT_STORE_FULL_INT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_INT, \
+ arg_requirement, \
+ {.intv = default_value})
+#define ECORE_GETOPT_STORE_FULL_LONG(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_LONG, \
+ arg_requirement, \
+ {.longv = default_value})
+#define ECORE_GETOPT_STORE_FULL_USHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_USHORT, \
+ arg_requirement, \
+ {.ushortv = default_value})
+#define ECORE_GETOPT_STORE_FULL_UINT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_UINT, \
+ arg_requirement, \
+ {.uintv, default_value})
+#define ECORE_GETOPT_STORE_FULL_ULONG(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_ULONG, \
+ arg_requirement, \
+ {.ulongv = default_value})
+#define ECORE_GETOPT_STORE_FULL_DOUBLE(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_DOUBLE, \
+ arg_requirement, \
+ {.doublev = default_value})
+
+#define ECORE_GETOPT_STORE_CONST(shortname, longname, help, value) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_CONST, \
+ {.store_const = value}}
+#define ECORE_GETOPT_STORE_TRUE(shortname, longname, help) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_TRUE, \
+ {.dummy = NULL}}
+#define ECORE_GETOPT_STORE_FALSE(shortname, longname, help) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_FALSE, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_CHOICE(shortname, longname, help, choices_array) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_CHOICE, \
+ {.choices = choices_array}}
+#define ECORE_GETOPT_CHOICE_METAVAR(shortname, longname, help, metavar, choices_array) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CHOICE, \
+ {.choices = choices_array}}
+
+
+#define ECORE_GETOPT_APPEND(shortname, longname, help, sub_type) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_APPEND, \
+ {.append_type = sub_type}}
+#define ECORE_GETOPT_APPEND_METAVAR(shortname, longname, help, metavar, type) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_APPEND, \
+ {.append_type = type}}
+
+#define ECORE_GETOPT_COUNT(shortname, longname, help) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_COUNT, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, callback_func, callback_data, argument_requirement, default_value) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CALLBACK, \
+ {.callback = {callback_func, callback_data, \
+ argument_requirement, default_value}}}
+#define ECORE_GETOPT_CALLBACK_NOARGS(shortname, longname, help, callback_func, callback_data) \
+ ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, NULL, \
+ callback_func, callback_data, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO, \
+ NULL)
+#define ECORE_GETOPT_CALLBACK_ARGS(shortname, longname, help, metavar, callback_func, callback_data) \
+ ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, \
+ callback_func, callback_data, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, \
+ NULL)
+
+#define ECORE_GETOPT_HELP(shortname, longname) \
+ {shortname, longname, "show this message.", NULL, \
+ ECORE_GETOPT_ACTION_HELP, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_VERSION(shortname, longname) \
+ {shortname, longname, "show program version.", NULL, \
+ ECORE_GETOPT_ACTION_VERSION, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_COPYRIGHT(shortname, longname) \
+ {shortname, longname, "show copyright.", NULL, \
+ ECORE_GETOPT_ACTION_COPYRIGHT, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_LICENSE(shortname, longname) \
+ {shortname, longname, "show license.", NULL, \
+ ECORE_GETOPT_ACTION_LICENSE, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_SENTINEL {0, NULL, NULL, NULL, 0, {.dummy = NULL}}
+
+#define ECORE_GETOPT_VALUE_STR(val) {.strp = &(val)}
+#define ECORE_GETOPT_VALUE_BOOL(val) {.boolp = &(val)}
+#define ECORE_GETOPT_VALUE_SHORT(val) {.shortp = &(val)}
+#define ECORE_GETOPT_VALUE_INT(val) {.intp = &(val)}
+#define ECORE_GETOPT_VALUE_LONG(val) {.longp = &(val)}
+#define ECORE_GETOPT_VALUE_USHORT(val) {.ushortp = &(val)}
+#define ECORE_GETOPT_VALUE_UINT(val) {.uintp = &(val)}
+#define ECORE_GETOPT_VALUE_ULONG(val) {.ulongp = &(val)}
+#define ECORE_GETOPT_VALUE_DOUBLE(val) {.doublep = &(val)}
+#define ECORE_GETOPT_VALUE_PTR(val) {.ptrp = &(val)}
+#define ECORE_GETOPT_VALUE_PTR_CAST(val) {.ptrp = (void **)&(val)}
+#define ECORE_GETOPT_VALUE_LIST(val) {.listp = &(val)}
+#define ECORE_GETOPT_VALUE_NONE {.ptrp = NULL}
+
+ EAPI void ecore_getopt_help(FILE *fp, const Ecore_Getopt *info);
+
+ EAPI unsigned char ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser);
+ EAPI int ecore_getopt_parse(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc, char **argv);
+
+ EAPI Eina_List *ecore_getopt_list_free(Eina_List *list);
+
+ /* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */
+ EAPI unsigned char ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
+ EAPI unsigned char ecore_getopt_callback_size_parse(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ECORE_GETOPT_H */
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = @GLIB_CFLAGS@ @EVIL_CFLAGS@ @EINA_CFLAGS@ @WIN32_CPPFLAGS@ @EFL_ECORE_BUILD@
+AM_CFLAGS = @WIN32_CFLAGS@ @EFL_PTHREAD_CFLAGS@
+
+lib_LTLIBRARIES = libecore.la
+include_HEADERS = \
+Ecore.h \
+Ecore_Getopt.h
+
+libecore_la_SOURCES = \
+ecore.c \
+ecore_anim.c \
+ecore_app.c \
+ecore_events.c \
+ecore_getopt.c \
+ecore_idle_enterer.c \
+ecore_idle_exiter.c \
+ecore_idler.c \
+ecore_job.c \
+ecore_main.c \
+ecore_pipe.c \
+ecore_poll.c \
+ecore_time.c \
+ecore_timer.c \
+ecore_thread.c \
+ecore_glib.c
+
+if ECORE_HAVE_WIN32
+
+libecore_la_SOURCES += ecore_exe_win32.c
+
+else
+
+if ECORE_HAVE_WINCE
+
+libecore_la_SOURCES += ecore_exe_wince.c
+
+else
+
+libecore_la_SOURCES += ecore_signal.c ecore_exe.c
+
+endif
+
+endif
+
+libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ -lm
+libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_release_info@
+
+EXTRA_DIST = ecore_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#ifndef _MSC_VER
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+#include <Eina.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#if HAVE_MALLINFO
+#include <malloc.h>
+
+#define KEEP_MAX(Global, Local) \
+ if (Global < (Local)) \
+ Global = Local;
+
+static int _ecore_memory_statistic(void *data);
+static int _ecore_memory_max_total = 0;
+static int _ecore_memory_max_free = 0;
+static pid_t _ecore_memory_pid = 0;
+#endif
+
+static const char *_ecore_magic_string_get(Ecore_Magic m);
+static int _ecore_init_count = 0;
+int _ecore_log_dom = -1;
+int _ecore_fps_debug = 0;
+
+/** OpenBSD does not define CODESET
+ * FIXME ??
+ */
+
+#ifndef CODESET
+# define CODESET "INVALID"
+#endif
+
+/**
+ * Set up connections, signal handlers, sockets etc.
+ * @return 1 or greater on success, 0 otherwise
+ *
+ * This function sets up all singal handlers and the basic event loop. If it
+ * succeeds, 1 will be returned, otherwise 0 will be returned.
+ *
+ * @code
+ * #include <Ecore.h>
+ *
+ * int main(int argc, char **argv)
+ * {
+ * if (!ecore_init())
+ * {
+ * printf("ERROR: Cannot init Ecore!\n");
+ * return -1;
+ * }
+ * ecore_main_loop_begin();
+ * ecore_shutdown();
+ * }
+ * @endcode
+ */
+EAPI int
+ecore_init(void)
+{
+ if (++_ecore_init_count != 1)
+ return _ecore_init_count;
+
+#ifdef HAVE_LOCALE_H
+ setlocale(LC_CTYPE, "");
+#endif
+ /*
+ if (strcmp(nl_langinfo(CODESET), "UTF-8"))
+ {
+ WRN("Not a utf8 locale!");
+ }
+ */
+#ifdef HAVE_EVIL
+ if (!evil_init())
+ return --_ecore_init_count;
+#endif
+ if (!eina_init())
+ goto shutdown_evil;
+ _ecore_log_dom = eina_log_domain_register("Ecore",ECORE_DEFAULT_LOG_COLOR);
+ if (_ecore_log_dom < 0) {
+ EINA_LOG_ERR("Ecore was unable to create a log domain.");
+ goto shutdown_log_dom;
+ }
+ if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
+ if (_ecore_fps_debug) _ecore_fps_debug_init();
+ _ecore_signal_init();
+ _ecore_exe_init();
+ _ecore_thread_init();
+ _ecore_glib_init();
+ _ecore_job_init();
+ _ecore_loop_time = ecore_time_get();
+
+#if HAVE_MALLINFO
+ if (getenv("ECORE_MEM_STAT"))
+ {
+ _ecore_memory_pid = getpid();
+ ecore_animator_add(_ecore_memory_statistic, NULL);
+ }
+#endif
+
+#ifdef GLIB_INTEGRATION_ALWAYS
+ if (_ecore_glib_always_integrate) ecore_main_loop_glib_integrate();
+#endif
+
+ return _ecore_init_count;
+
+ shutdown_log_dom:
+ eina_shutdown();
+ shutdown_evil:
+#ifdef HAVE_EVIL
+ evil_shutdown();
+#endif
+ return --_ecore_init_count;
+}
+
+/**
+ * Shut down connections, signal handlers sockets etc.
+ *
+ * This function shuts down all things set up in ecore_init() and cleans up all
+ * event queues, handlers, filters, timers, idlers, idle enterers/exiters
+ * etc. set up after ecore_init() was called.
+ *
+ * Do not call this function from any callback that may be called from the main
+ * loop, as the main loop will then fall over and not function properly.
+ */
+EAPI int
+ecore_shutdown(void)
+{
+ if (--_ecore_init_count != 0)
+ return _ecore_init_count;
+
+ if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
+ _ecore_poller_shutdown();
+ _ecore_animator_shutdown();
+ _ecore_glib_shutdown();
+ _ecore_job_shutdown();
+ _ecore_thread_shutdown();
+ _ecore_exe_shutdown();
+ _ecore_idle_enterer_shutdown();
+ _ecore_idle_exiter_shutdown();
+ _ecore_idler_shutdown();
+ _ecore_timer_shutdown();
+ _ecore_event_shutdown();
+ _ecore_main_shutdown();
+ _ecore_signal_shutdown();
+
+#if HAVE_MALLINFO
+ if (getenv("ECORE_MEM_STAT"))
+ {
+ _ecore_memory_statistic(NULL);
+
+ ERR("[%i] Memory MAX total: %i, free: %i",
+ _ecore_memory_pid,
+ _ecore_memory_max_total,
+ _ecore_memory_max_free);
+ }
+#endif
+
+ eina_log_domain_unregister(_ecore_log_dom);
+ _ecore_log_dom = -1;
+ eina_shutdown();
+#ifdef HAVE_EVIL
+ evil_shutdown();
+#endif
+
+ return _ecore_init_count;
+}
+
+EAPI void
+ecore_print_warning(const char *function, const char *sparam)
+{
+ WRN("***** Developer Warning ***** :\n"
+ "\tThis program is calling:\n\n"
+ "\t%s();\n\n"
+ "\tWith the parameter:\n\n"
+ "\t%s\n\n"
+ "\tbeing NULL. Please fix your program.", function, sparam);
+ if (getenv("ECORE_ERROR_ABORT")) abort();
+}
+
+EAPI void
+_ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname)
+{
+ ERR("\n"
+ "*** ECORE ERROR: Ecore Magic Check Failed!!!\n"
+ "*** IN FUNCTION: %s()", fname);
+ if (!d)
+ ERR(" Input handle pointer is NULL!");
+ else if (m == ECORE_MAGIC_NONE)
+ ERR(" Input handle has already been freed!");
+ else if (m != req_m)
+ ERR(" Input handle is wrong type\n"
+ " Expected: %08x - %s\n"
+ " Supplied: %08x - %s",
+ (unsigned int)req_m, _ecore_magic_string_get(req_m),
+ (unsigned int)m, _ecore_magic_string_get(m));
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Now go fix your code. Tut tut tut!");
+ if (getenv("ECORE_ERROR_ABORT")) abort();
+}
+
+static const char *
+_ecore_magic_string_get(Ecore_Magic m)
+{
+ switch (m)
+ {
+ case ECORE_MAGIC_NONE:
+ return "None (Freed Object)";
+ break;
+ case ECORE_MAGIC_EXE:
+ return "Ecore_Exe (Executable)";
+ break;
+ case ECORE_MAGIC_TIMER:
+ return "Ecore_Timer (Timer)";
+ break;
+ case ECORE_MAGIC_IDLER:
+ return "Ecore_Idler (Idler)";
+ break;
+ case ECORE_MAGIC_IDLE_ENTERER:
+ return "Ecore_Idle_Enterer (Idler Enterer)";
+ break;
+ case ECORE_MAGIC_IDLE_EXITER:
+ return "Ecore_Idle_Exiter (Idler Exiter)";
+ break;
+ case ECORE_MAGIC_FD_HANDLER:
+ return "Ecore_Fd_Handler (Fd Handler)";
+ break;
+ case ECORE_MAGIC_WIN32_HANDLER:
+ return "Ecore_Win32_Handler (Win32 Handler)";
+ break;
+ case ECORE_MAGIC_EVENT_HANDLER:
+ return "Ecore_Event_Handler (Event Handler)";
+ break;
+ case ECORE_MAGIC_EVENT:
+ return "Ecore_Event (Event)";
+ break;
+ default:
+ return "<UNKNOWN>";
+ };
+}
+
+/* fps debug calls - for debugging how much time your app actually spends */
+/* "running" (and the inverse being time spent running)... this does not */
+/* account for other apps and multitasking... */
+
+static int _ecore_fps_debug_init_count = 0;
+static int _ecore_fps_debug_fd = -1;
+unsigned int *_ecore_fps_runtime_mmap = NULL;
+
+void
+_ecore_fps_debug_init(void)
+{
+ char buf[4096];
+ const char *tmp;
+ int pid;
+
+ _ecore_fps_debug_init_count++;
+ if (_ecore_fps_debug_init_count > 1) return;
+
+#ifndef HAVE_EVIL
+ tmp = "/tmp";
+#else
+ tmp = (char *)evil_tmpdir_get ();
+#endif /* HAVE_EVIL */
+ pid = (int)getpid();
+ snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
+ _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
+ if (_ecore_fps_debug_fd < 0)
+ {
+ unlink(buf);
+ _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
+ }
+ if (_ecore_fps_debug_fd >= 0)
+ {
+ unsigned int zero = 0;
+ char *buf = (char *)&zero;
+ ssize_t todo = sizeof(unsigned int);
+
+ while (todo > 0)
+ {
+ ssize_t r = write(_ecore_fps_debug_fd, buf, todo);
+ if (r > 0)
+ {
+ todo -= r;
+ buf += r;
+ }
+ else if ((r < 0) && (errno == EINTR))
+ continue;
+ else
+ {
+ ERR("could not write to file '%s' fd %d: %s",
+ tmp, _ecore_fps_debug_fd, strerror(errno));
+ close(_ecore_fps_debug_fd);
+ _ecore_fps_debug_fd = -1;
+ return;
+ }
+ }
+ _ecore_fps_runtime_mmap = mmap(NULL, sizeof(unsigned int),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ _ecore_fps_debug_fd, 0);
+ if (_ecore_fps_runtime_mmap == MAP_FAILED)
+ _ecore_fps_runtime_mmap = NULL;
+ }
+}
+
+void
+_ecore_fps_debug_shutdown(void)
+{
+ _ecore_fps_debug_init_count--;
+ if (_ecore_fps_debug_init_count > 0) return;
+ if (_ecore_fps_debug_fd >= 0)
+ {
+ char buf[4096];
+ const char *tmp;
+ int pid;
+
+#ifndef HAVE_EVIL
+ tmp = "/tmp";
+#else
+ tmp = (char *)evil_tmpdir_get ();
+#endif /* HAVE_EVIL */
+ pid = (int)getpid();
+ snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
+ unlink(buf);
+ if (_ecore_fps_runtime_mmap)
+ {
+ munmap(_ecore_fps_runtime_mmap, sizeof(int));
+ _ecore_fps_runtime_mmap = NULL;
+ }
+ close(_ecore_fps_debug_fd);
+ _ecore_fps_debug_fd = -1;
+ }
+}
+
+void
+_ecore_fps_debug_runtime_add(double t)
+{
+ if ((_ecore_fps_debug_fd >= 0) &&
+ (_ecore_fps_runtime_mmap))
+ {
+ unsigned int tm;
+
+ tm = (unsigned int)(t * 1000000.0);
+ /* i know its not 100% theoretically guaranteed, but i'd say a write */
+ /* of an int could be considered atomic for all practical purposes */
+ /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */
+ /* this can run for about 4294 seconds becore looping. if you are */
+ /* doing performance testing in one run for over an hour... well */
+ /* time to restart or handle a loop condition :) */
+ *(_ecore_fps_runtime_mmap) += tm;
+ }
+}
+
+#if HAVE_MALLINFO
+static int
+_ecore_memory_statistic(__UNUSED__ void *data)
+{
+ struct mallinfo mi;
+ static int uordblks = 0;
+ static int fordblks = 0;
+ Eina_Bool changed = EINA_FALSE;
+
+ mi = mallinfo();
+
+#define HAS_CHANGED(Global, Local) \
+ if (Global != Local) \
+ { \
+ Global = Local; \
+ changed = EINA_TRUE; \
+ }
+
+ HAS_CHANGED(uordblks, mi.uordblks);
+ HAS_CHANGED(fordblks, mi.fordblks);
+
+ if (changed)
+ ERR("[%i] Memory total: %i, free: %i",
+ _ecore_memory_pid,
+ mi.uordblks,
+ mi.fordblks);
+
+ KEEP_MAX(_ecore_memory_max_total, mi.uordblks);
+ KEEP_MAX(_ecore_memory_max_free, mi.fordblks);
+
+ return 1;
+}
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Animator
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+
+ int (*func) (void *data);
+ void *data;
+
+ Eina_Bool delete_me : 1;
+ Eina_Bool suspended : 1;
+};
+
+
+static int _ecore_animator(void *data);
+
+static Ecore_Timer *timer = NULL;
+static int animators_delete_me = 0;
+static Ecore_Animator *animators = NULL;
+static double animators_frametime = 1.0 / 30.0;
+
+/**
+ * Add a animator to tick off at every animaton tick during main loop execution.
+ * @param func The function to call when it ticks off
+ * @param data The data to pass to the function
+ * @return A handle to the new animator
+ * @ingroup Ecore_Animator_Group
+ *
+ * This function adds a animator and returns its handle on success and NULL on
+ * failure. The function @p func will be called every N seconds where N is the
+ * frametime interval set by ecore_animator_frametime_set(). The function will
+ * be passed the @p data pointer as its parameter.
+ *
+ * When the animator @p func is called, it must return a value of either 1 or 0.
+ * If it returns 1 (or ECORE_CALLBACK_RENEW), it will be called again at the
+ * next tick, or if it returns 0 (or ECORE_CALLBACK_CANCEL) it will be deleted
+ * automatically making any references/handles for it invalid.
+ */
+EAPI Ecore_Animator *
+ecore_animator_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Animator *animator;
+
+ if (!func) return NULL;
+ animator = calloc(1, sizeof(Ecore_Animator));
+ if (!animator) return NULL;
+ ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR);
+ animator->func = func;
+ animator->data = (void *)data;
+ animators = (Ecore_Animator *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
+ if (!timer)
+ {
+ double t_loop = ecore_loop_time_get();
+ double sync_0 = 0.0;
+ double d = -fmod(t_loop - sync_0, animators_frametime);
+
+ timer = ecore_timer_loop_add(animators_frametime, _ecore_animator, NULL);
+ ecore_timer_delay(timer, d);
+ }
+ return animator;
+}
+
+/**
+ * Delete the specified animator from the animator list.
+ * @param animator The animator to delete
+ * @return The data pointer set for the animator
+ * @ingroup Ecore_Animator_Group
+ *
+ * Delete the specified @p aqnimator from the set of animators that are executed
+ * during main loop execution. This function returns the data parameter that
+ * was being passed to the callback on success, or NULL on failure. After this
+ * call returns the specified animator object @p animator is invalid and should not
+ * be used again. It will not get called again after deletion.
+ */
+EAPI void *
+ecore_animator_del(Ecore_Animator *animator)
+{
+ if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
+ {
+ ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
+ "ecore_animator_del");
+ return NULL;
+ }
+ if (animator->delete_me) return animator->data;
+ animator->delete_me = EINA_TRUE;
+ animators_delete_me++;
+ return animator->data;
+}
+
+/**
+ * Set the animator call interval in seconds.
+ * @param frametime The time in seconds in between animator ticks.
+ *
+ * This function sets the time interval (in seconds) inbetween animator ticks.
+ */
+EAPI void
+ecore_animator_frametime_set(double frametime)
+{
+ if (frametime < 0.0) frametime = 0.0;
+ if (animators_frametime == frametime) return;
+ animators_frametime = frametime;
+ if (timer)
+ {
+ ecore_timer_del(timer);
+ timer = NULL;
+ }
+ if (animators)
+ timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL);
+}
+
+/**
+ * Get the animator call interval in seconds.
+ * @return The time in second in between animator ticks.
+ *
+ * this function retrieves the time inbetween animator ticks, in seconds.
+ */
+EAPI double
+ecore_animator_frametime_get(void)
+{
+ return animators_frametime;
+}
+
+/**
+ * Suspend the specified animator.
+ * @param animator The animator to delete
+ * @ingroup Ecore_Animator_Group
+ *
+ * The specified @p animator will be temporarly removed from the set of animators
+ * that are executed during main loop execution.
+ */
+EAPI void
+ecore_animator_freeze(Ecore_Animator *animator)
+{
+ if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
+ {
+ ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
+ "ecore_animator_del");
+ return;
+ }
+ if (animator->delete_me) return;
+ animator->suspended = EINA_TRUE;
+}
+
+/**
+ * Restore execution of the specified animator.
+ * @param animator The animator to delete
+ * @ingroup Ecore_Animator_Group
+ *
+ * The specified @p animator will be put back in the set of animators
+ * that are executed during main loop execution.
+ */
+EAPI void
+ecore_animator_thaw(Ecore_Animator *animator)
+{
+ if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
+ {
+ ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
+ "ecore_animator_del");
+ return;
+ }
+ if (animator->delete_me) return;
+ animator->suspended = EINA_FALSE;
+}
+
+void
+_ecore_animator_shutdown(void)
+{
+ if (timer)
+ {
+ ecore_timer_del(timer);
+ timer = NULL;
+ }
+ while (animators)
+ {
+ Ecore_Animator *animator;
+
+ animator = animators;
+ animators = (Ecore_Animator *) eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators));
+ ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
+ free(animator);
+ }
+}
+
+static int
+_ecore_animator(void *data __UNUSED__)
+{
+ Ecore_Animator *animator;
+
+ EINA_INLIST_FOREACH(animators, animator)
+ {
+ if (!animator->delete_me && !animator->suspended)
+ {
+ if (!animator->func(animator->data))
+ {
+ animator->delete_me = EINA_TRUE;
+ animators_delete_me++;
+ }
+ }
+ }
+ if (animators_delete_me)
+ {
+ Ecore_Animator *l;
+ for(l = animators; l;)
+ {
+ animator = l;
+ l = (Ecore_Animator *) EINA_INLIST_GET(l)->next;
+ if (animator->delete_me)
+ {
+ animators = (Ecore_Animator *) eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
+ ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
+ free(animator);
+ animators_delete_me--;
+ if (animators_delete_me == 0) break;
+ }
+ }
+ }
+ if (!animators)
+ {
+ timer = NULL;
+ return 0;
+ }
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#ifndef _MSC_VER
+# include <unistd.h>
+#else
+# include <process.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+static int app_argc = 0;
+static char **app_argv = NULL;
+
+/**
+ * Set up the programs command-line arguments.
+ * @param argc The same as passed as argc to the programs main() function
+ * @param argv The same as passed as argv to the programs main() function
+ *
+ * A call to this function will store the programs command-line arguments
+ * for later use by ecore_app_restart() or ecore_app_args_get().
+ */
+EAPI void
+ecore_app_args_set(int argc, const char **argv)
+{
+ if ((argc < 1) ||
+ (!argv)) return;
+ app_argc = argc;
+ app_argv = (char **)argv;
+}
+
+/**
+ * Return the programs stored command-line arguments.
+ * @param argc A pointer to the return value to hold argc
+ * @param argv A pointer to the return value to hold argv
+ *
+ * When called, this funciton returns the arguments for the program stored by
+ * ecore_app_args_set(). The integer pointed to by @p argc will be filled, if
+ * the pointer is not NULL, and the string array pointer @p argv will be filled
+ * also if the pointer is not NULL. The values they are filled with will be the
+ * same set by ecore_app_args_set().
+ */
+EAPI void
+ecore_app_args_get(int *argc, char ***argv)
+{
+ if (argc) *argc = app_argc;
+ if (argv) *argv = app_argv;
+}
+
+/**
+ * Restart the program executable with the command-line arguments stored.
+ *
+ * This function will restart & re-execute this program in place of itself
+ * using the command-line arguments stored by ecore_app_args_set(). This is
+ * an easy way for a program to restart itself for cleanup purposes,
+ * configuration reasons or in the event of a crash.
+ */
+EAPI void
+ecore_app_restart(void)
+{
+ char *args[4096];
+ int i;
+
+ if ((app_argc < 1) || (!app_argv)) return;
+ if (app_argc >= 4096) return;
+ for (i = 0; i < app_argc; i++) args[i] = app_argv[i];
+ args[i] = NULL;
+ execvp(app_argv[0], args);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Event_Handler
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ int type;
+ int (*func) (void *data, int type, void *event);
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
+};
+
+struct _Ecore_Event_Filter
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ void *(*func_start) (void *data);
+ int (*func_filter) (void *data, void *loop_data, int type, void *event);
+ void (*func_end) (void *data, void *loop_data);
+ void *loop_data;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
+};
+
+struct _Ecore_Event
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ int type;
+ void *event;
+ void (*func_free) (void *data, void *ev);
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
+};
+
+
+static int events_num = 0;
+static Ecore_Event *events = NULL;
+static Ecore_Event *event_current = NULL;
+
+static Ecore_Event_Handler **event_handlers = NULL;
+static Ecore_Event_Handler *event_handler_current = NULL;
+static int event_handlers_num = 0;
+static int event_handlers_alloc_num = 0;
+static Eina_List *event_handlers_delete_list = NULL;
+
+static Ecore_Event_Filter *event_filters = NULL;
+static Ecore_Event_Filter *event_filter_current = NULL;
+static int event_filters_delete_me = 0;
+static int event_id_max = ECORE_EVENT_COUNT;
+static int ecore_raw_event_type = ECORE_EVENT_NONE;
+static void *ecore_raw_event_event = NULL;
+
+
+static void _ecore_event_purge_deleted(void);
+static void *_ecore_event_del(Ecore_Event *event);
+
+
+/**
+ * Add an event handler.
+ * @param type The type of the event this handler will get called for
+ * @param func The function to call when the event is found in the queue
+ * @param data A data pointer to pass to the called function @p func
+ * @return A new Event handler, or NULL on failure
+ *
+ * Add an event handler to the list of handlers. This will, on success, return
+ * a handle to the event handler object that was created, that can be used
+ * later to remove the handler using ecore_event_handler_del(). The @p type
+ * parameter is the integer of the event type that will trigger this callback
+ * to be called. The callback @p func is called when this event is processed
+ * and will be passed the event type, a pointer to the private event
+ * structure that is specific to that event type, and a data pointer that is
+ * provided in this call as the @p data parameter.
+ *
+ * When the callback @p func is called, it must return 1 or 0. If it returns
+ * 1 (or ECORE_CALLBACK_RENEW), It will keep being called as per normal, for
+ * each handler set up for that event type. If it returns 0 (or
+ * ECORE_CALLBACK_CANCEL), it will cease processing handlers for that particular
+ * event, so all handler set to handle that event type that have not already
+ * been called, will not be.
+ */
+EAPI Ecore_Event_Handler *
+ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data)
+{
+ Ecore_Event_Handler *eh;
+
+ if (!func) return NULL;
+ if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL;
+ eh = calloc(1, sizeof(Ecore_Event_Handler));
+ if (!eh) return NULL;
+ ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
+ eh->type = type;
+ eh->func = func;
+ eh->data = (void *)data;
+ if (type >= (event_handlers_num - 1))
+ {
+ int p_alloc_num;
+
+ p_alloc_num = event_handlers_alloc_num;
+ event_handlers_num = type + 1;
+ if (event_handlers_num > event_handlers_alloc_num)
+ {
+ Ecore_Event_Handler **new_handlers;
+ int i;
+
+ event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16;
+ new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
+ if (!new_handlers)
+ {
+ free(eh);
+ return NULL;
+ }
+ event_handlers = new_handlers;
+ for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
+ event_handlers[i] = NULL;
+ }
+ }
+ event_handlers[type] = (Ecore_Event_Handler *) eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh));
+ return eh;
+}
+
+/**
+ * Delete an event handler.
+ * @param event_handler Event handler handle to delete
+ * @return Data passed to handler
+ *
+ * Delete a specified event handler from the handler list. On success this will
+ * delete the event handler and return the pointer passed as @p data when the
+ * handler was added by ecore_event_handler_add(). On failure NULL will be
+ * returned. Once a handler is deleted it will no longer be called.
+ */
+EAPI void *
+ecore_event_handler_del(Ecore_Event_Handler *event_handler)
+{
+ if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
+ "ecore_event_handler_del");
+ return NULL;
+ }
+ event_handler->delete_me = 1;
+ event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler);
+ return event_handler->data;
+}
+
+static void
+_ecore_event_generic_free (void *data __UNUSED__, void *event)
+{
+ free (event);
+}
+
+/**
+ * Add an event to the event queue.
+ * @param type The event type to add to the end of the event queue
+ * @param ev The private data structure for this event type
+ * @param func_free The function to be called to free this private structure
+ * @param data The data pointer to be passed to the free function
+ * @return A Handle for that event
+ *
+ * On success this function returns a handle to an event on the event queue, or
+ * NULL if it fails. If it succeeds, an event of type @p type will be added
+ * to the queue for processing by event handlers added by
+ * ecore_event_handler_add(). The @p ev parameter will be a pointer to the event
+ * private data that is specific to that event type. When the event is no
+ * longer needed, @p func_free will be called and passed the private structure
+ * pointer for cleaning up. If @p func_free is NULL, free() will be called
+ * with the private structure pointer.
+ * func_free is passed @p data as its data parameter.
+ */
+EAPI Ecore_Event *
+ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data)
+{
+/* if (!ev) return NULL;*/
+ if (type <= ECORE_EVENT_NONE) return NULL;
+ if (type >= event_id_max) return NULL;
+ if ((ev) && (!func_free)) func_free = _ecore_event_generic_free;
+ return _ecore_event_add(type, ev, func_free, data);
+}
+
+/**
+ * Delete an event from the queue.
+ * @param event The event handle to delete
+ * @return The data pointer originally set for the event free function
+ *
+ * This deletes the event @p event from the event queue, and returns the
+ * @p data parameer originally set when adding it with ecore_event_add(). This
+ * does not immediately call the free function, and it may be called later on
+ * cleanup, and so if the free function depends on the data pointer to work,
+ * you should defer cleaning of this till the free function is called later.
+ */
+EAPI void *
+ecore_event_del(Ecore_Event *event)
+{
+ if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT))
+ {
+ ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del");
+ return NULL;
+ }
+ event->delete_me = 1;
+ return event->data;
+}
+
+/**
+ * Allocate a new event type id sensibly and return the new id.
+ * @return A new event type id.
+ *
+ * This function allocates a new event type id and returns it. Once an event
+ * type has been allocated it can never be de-allocated during the life of
+ * the program. There is no guarantee of the contents of this event ID, or how
+ * it is calculated, except that the ID will be unique to the current instance
+ * of the process.
+ */
+EAPI int
+ecore_event_type_new(void)
+{
+ event_id_max++;
+ return event_id_max - 1;
+}
+
+/**
+ * Add a filter the current event queue.
+ * @param func_start Function to call just before filtering and return data
+ * @param func_filter Function to call on each event
+ * @param func_end Function to call after the queu has been filtered
+ * @param data Data to pass to the filter functions
+ * @return A filter handle
+ *
+ * This adds a filter to call callbacks to loop through the event queue and
+ * filter events out of the queue. On failure NULL is returned. On success a
+ * Filter handle is returned. Filters are called on the queue just before
+ * Event handler processing to try and remove redundant events. Just as
+ * processing starts @p func_start is called and passed the @p data pointer.
+ * This function returns a pointer that is used as loop_data that is now passed to
+ * @p func_filter as loop_data. @p func_filter is also passed @p data and the
+ * event type and private event structure. If this callback returns 0, the
+ * event is removed from the queue. If it returns 1, the event is kept. When
+ * processing is finished @p func_end is called and is passed the loop_data
+ * and @p data pointer to clean up.
+ */
+EAPI Ecore_Event_Filter *
+ecore_event_filter_add(void * (*func_start) (void *data), int (*func_filter) (void *data, void *loop_data, int type, void *event), void (*func_end) (void *data, void *loop_data), const void *data)
+{
+ Ecore_Event_Filter *ef;
+
+ if (!func_filter) return NULL;
+ ef = calloc(1, sizeof(Ecore_Event_Filter));
+ if (!ef) return NULL;
+ ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
+ ef->func_start = func_start;
+ ef->func_filter = func_filter;
+ ef->func_end = func_end;
+ ef->data = (void *)data;
+ event_filters = (Ecore_Event_Filter *) eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
+ return ef;
+}
+
+/**
+ * Delete an event filter.
+ * @param ef The event filter handle
+ * @return The data set for the filter
+ *
+ * Delete a filter that has been added by its @p ef handle. On success this
+ * will return the data pointer set when this filter was added. On failure
+ * NULL is returned.
+ */
+EAPI void *
+ecore_event_filter_del(Ecore_Event_Filter *ef)
+{
+ if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
+ {
+ ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
+ return NULL;
+ }
+ ef->delete_me = 1;
+ event_filters_delete_me = 1;
+ return ef->data;
+}
+
+/**
+ * Return the current event type being handled.
+ * @return The current event type being handled if inside a handler callback
+ *
+ * If the program is currently inside an Ecore event handler callback this
+ * will return the type of the current event being processed. If Ecore is
+ * not inside an event handler, ECORE_EVENT_NONE is returned.
+ *
+ * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
+ * events and not all the original information is passed on. In special cases
+ * this extra information may be useful or needed and using this call can let
+ * the program know if the event type being handled is one it wants to get more
+ * information about.
+ */
+EAPI int
+ecore_event_current_type_get(void)
+{
+ return ecore_raw_event_type;
+}
+
+/**
+ * Return the current event type pointer handled.
+ * @return The current event pointer being handled if inside a handler callback
+ *
+ * If the program is currently inside an Ecore event handler callback this
+ * will return the pointer of the current event being processed. If Ecore is
+ * not inside an event handler, NULL will be returned.
+ *
+ * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
+ * events and not all the original information is passed on. In special cases
+ * this extra information may be useful or needed and using this call can let
+ * the program access the event data if the type of the event is handled by
+ * the program.
+ */
+EAPI void *
+ecore_event_current_event_get(void)
+{
+ return ecore_raw_event_event;
+}
+
+void
+_ecore_event_shutdown(void)
+{
+ int i;
+ Ecore_Event_Handler *eh;
+ Ecore_Event_Filter *ef;
+
+ while (events) _ecore_event_del(events);
+ event_current = NULL;
+ for (i = 0; i < event_handlers_num; i++)
+ {
+ while ((eh = event_handlers[i]))
+ {
+ event_handlers[i] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
+ ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
+ if (!eh->delete_me) free(eh);
+ }
+ }
+ EINA_LIST_FREE(event_handlers_delete_list, eh)
+ free(eh);
+ if (event_handlers) free(event_handlers);
+ event_handlers = NULL;
+ event_handlers_num = 0;
+ event_handlers_alloc_num = 0;
+ while ((ef = event_filters))
+ {
+ event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
+ ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
+ free(ef);
+ }
+ event_filters_delete_me = 0;
+ event_filter_current = NULL;
+}
+
+int
+_ecore_event_exist(void)
+{
+ if (events) return 1;
+ return 0;
+}
+
+Ecore_Event *
+_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data)
+{
+ Ecore_Event *e;
+
+ e = calloc(1, sizeof(Ecore_Event));
+ if (!e) return NULL;
+ ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
+ e->type = type;
+ e->event = ev;
+ e->func_free = func_free;
+ e->data = data;
+ events = (Ecore_Event *) eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
+ events_num++;
+ return e;
+}
+
+void *
+_ecore_event_del(Ecore_Event *event)
+{
+ void *data;
+
+ data = event->data;
+ if (event->func_free) event->func_free(event->data, event->event);
+ events = (Ecore_Event *) eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
+ ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
+ free(event);
+ events_num--;
+ return data;
+}
+
+static void
+_ecore_event_purge_deleted(void)
+{
+ Ecore_Event *itr = events;
+
+ while (itr)
+ {
+ Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
+ if (!itr->references)
+ _ecore_event_del(itr);
+ itr = next;
+ }
+}
+
+void
+_ecore_event_call(void)
+{
+ Eina_List *l, *l_next;
+ Ecore_Event_Handler *eh;
+
+ if (!event_filter_current)
+ {
+ /* regular main loop, start from head */
+ event_filter_current = event_filters;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
+ }
+
+ while (event_filter_current)
+ {
+ Ecore_Event_Filter *ef = event_filter_current;
+
+ if (!ef->delete_me)
+ {
+ ef->references++;
+
+ if (ef->func_start)
+ ef->loop_data = ef->func_start(ef->data);
+
+ if (!event_current)
+ {
+ /* regular main loop, start from head */
+ event_current = events;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
+ }
+
+ while (event_current)
+ {
+ Ecore_Event *e = event_current;
+
+ if (!ef->func_filter(ef->loop_data, ef->data,
+ e->type, e->event))
+ {
+// printf("FILTER SAID TO DEL ev %p\n", e->event);
+ ecore_event_del(e);
+ }
+
+ if (event_current) /* may have changed in recursive main loops */
+ event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
+ }
+ if (ef->func_end)
+ ef->func_end(ef->data, ef->loop_data);
+
+ ef->references--;
+ }
+
+ if (event_filter_current) /* may have changed in recursive main loops */
+ event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
+ }
+ if (event_filters_delete_me)
+ {
+ int deleted_in_use = 0;
+ Ecore_Event_Filter *l;
+ for (l = event_filters; l;)
+ {
+ Ecore_Event_Filter *ef = l;
+ l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)->next;
+ if (ef->delete_me)
+ {
+ if (ef->references)
+ {
+ deleted_in_use++;
+ continue;
+ }
+
+ event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
+ ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
+ free(ef);
+ }
+ }
+ if (!deleted_in_use)
+ event_filters_delete_me = 0;
+ }
+
+// printf("EVENT BATCH...\n");
+
+ if (!event_current)
+ {
+ /* regular main loop, start from head */
+ event_current = events;
+ event_handler_current = NULL;
+ }
+
+ while (event_current)
+ {
+ Ecore_Event *e = event_current;
+
+ if (!e->delete_me)
+ {
+ int handle_count = 0;
+ ecore_raw_event_type = e->type;
+ ecore_raw_event_event = e->event;
+ e->references++;
+// printf("HANDLE ev type %i, %p\n", e->type, e->event);
+ if ((e->type >= 0) && (e->type < event_handlers_num))
+ {
+ if (!event_handler_current)
+ {
+ /* regular main loop, start from head */
+ event_handler_current = event_handlers[e->type];
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ event_handler_current= (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
+ }
+
+ while ((event_handler_current) && (!e->delete_me))
+ {
+ Ecore_Event_Handler *eh = event_handler_current;
+ if (!eh->delete_me)
+ {
+ int ret;
+
+ handle_count++;
+
+ eh->references++;
+ ret = eh->func(eh->data, e->type, e->event);
+ eh->references--;
+
+ if (!ret)
+ {
+ event_handler_current = NULL;
+ break; /* 0 == "call no further handlers" */
+ }
+ }
+ if (event_handler_current) /* may have changed in recursive main loops */
+ event_handler_current= (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
+ }
+ }
+ /* if no handlers were set for EXIT signal - then default is */
+ /* to quit the main loop */
+ if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0))
+ ecore_main_loop_quit();
+ e->references--;
+ }
+
+ if (event_current) /* may have changed in recursive main loops */
+ event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
+ }
+// printf("EVENT BATCH DONE\n");
+ ecore_raw_event_type = ECORE_EVENT_NONE;
+ ecore_raw_event_event = NULL;
+
+ _ecore_event_purge_deleted();
+ EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
+ {
+ if (eh->references) continue;
+
+ event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
+
+ event_handlers[eh->type] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
+ ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
+ free(eh);
+ }
+}
+
+EAPI void *
+_ecore_event_signal_user_new(void)
+{
+ Ecore_Event_Signal_User *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_User));
+ return e;
+}
+
+void *
+_ecore_event_signal_hup_new(void)
+{
+ Ecore_Event_Signal_Hup *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
+ return e;
+}
+
+void *
+_ecore_event_signal_exit_new(void)
+{
+ Ecore_Event_Signal_Exit *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
+ return e;
+}
+
+void *
+_ecore_event_signal_power_new(void)
+{
+ Ecore_Event_Signal_Power *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Signal_Power));
+ return e;
+}
+
+void *
+_ecore_event_signal_realtime_new(void)
+{
+ return calloc(1, sizeof(Ecore_Event_Signal_Realtime));
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__)
+# include <sys/time.h>
+# include <sys/resource.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+ /* FIXME: Getting respawn to work
+ *
+ * There is no way that we can do anything about the internal state info of
+ * an external exe. The same can be said about the state of user code. User
+ * code in this context means the code that is using ecore_exe to manage exe's
+ * for it.
+ *
+ * Document that the exe must be respawnable, in other words, there is no
+ * state that it cannot regenerate by just killing it and starting it again.
+ * This includes state that the user code knows about, as the respawn is
+ * transparent to that code. On the other hand, maybe a respawn event might
+ * be useful, or maybe resend the currently non existant add event. For
+ * consistancy with ecore_con, an add event is good anyway.
+ *
+ * The Ecore_exe structure is reused for respawning, so that the (opaque)
+ * pointer held by the user remains valid. This means that the Ecore_Exe
+ * init and del functions may need to be split into two parts each to avoid
+ * duplicating code - common code part, and the rest. This implies that
+ * the unchanging members mentioned next should NEVER change.
+ *
+ * These structure members don't need to change -
+ * __list_data - we stay on the list
+ * ECORE_MAGIC - this is a constant
+ * data - passed in originally
+ * cmd - passed in originally
+ * flags - passed in originally
+ *
+ * These structure members need to change -
+ * tag - state that must be regenerated, zap it
+ * pid - it will be different
+ * child_fd_write - it will be different
+ * child_fd_read - it will be different
+ * child_fd_error - it will be different
+ * write_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
+ * read_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
+ * error_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
+ *
+ * Hmm, the read, write, and error buffers could be tricky.
+ * They are not atomic, and could be in a semi complete state.
+ * They fall into the "state must be regenerated" mentioned above.
+ * A respawn/add event should take care of it.
+ *
+ * These structure members need to change -
+ * write_data_buf - state that must be regenerated, zap it
+ * write_data_size - state that must be regenerated, zap it
+ * write_data_offset - state that must be regenerated, zap it
+ * read_data_buf - state that must be regenerated, zap it
+ * read_data_size - state that must be regenerated, zap it
+ * error_data_buf - state that must be regenerated, zap it
+ * error_data_size - state that must be regenerated, zap it
+ * close_write - state that must be regenerated, zap it
+ *
+ * There is the problem that an exe that fell over and needs respawning
+ * might keep falling over, keep needing to be respawned, and tie up system
+ * resources with the constant respawning. An exponentially increasing
+ * timeout (with maximum timeout) between respawns should take care of that.
+ * Although this is not a "contention for a resource" problem, the exe falling
+ * over may be, so a random element added to the timeout may help, and won't
+ * hurt. The user code may need to be informed that a timeout is in progress.
+ */
+
+struct _Ecore_Exe
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ pid_t pid;
+ void *data;
+ char *tag, *cmd;
+ Ecore_Exe_Flags flags;
+ Ecore_Fd_Handler *write_fd_handler; /* the fd_handler to handle write to child - if this was used, or NULL if not */
+ Ecore_Fd_Handler *read_fd_handler; /* the fd_handler to handle read from child - if this was used, or NULL if not */
+ Ecore_Fd_Handler *error_fd_handler; /* the fd_handler to handle errors from child - if this was used, or NULL if not */
+ void *write_data_buf; /* a data buffer for data to write to the child -
+ * realloced as needed for more data and flushed when the fd handler says writes are possible
+ */
+ int write_data_size; /* the size in bytes of the data buffer */
+ int write_data_offset; /* the offset in bytes in the data buffer */
+ void *read_data_buf; /* data read from the child awating delivery to an event */
+ int read_data_size; /* data read from child in bytes */
+ void *error_data_buf; /* errors read from the child awating delivery to an event */
+ int error_data_size; /* errors read from child in bytes */
+ int child_fd_write; /* fd to write TO to send data to the child */
+ int child_fd_read; /* fd to read FROM when child has sent us (the parent) data */
+ int child_fd_error; /* fd to read FROM when child has sent us (the parent) errors */
+ int child_fd_write_x; /* fd to write TO to send data to the child */
+ int child_fd_read_x; /* fd to read FROM when child has sent us (the parent) data */
+ int child_fd_error_x; /* fd to read FROM when child has sent us (the parent) errors */
+ Eina_Bool close_stdin : 1;
+
+ int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */
+
+ Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */
+ void *doomsday_clock_dead; /* data for the doomsday clock */
+
+ void (*pre_free_cb)(void *data, const Ecore_Exe *exe);
+};
+
+
+/* TODO: Something to let people build a command line and does auto escaping -
+ *
+ * ecore_exe_snprintf()
+ *
+ * OR
+ *
+ * cmd = ecore_exe_comand_parameter_append(cmd, "firefox");
+ * cmd = ecore_exe_comand_parameter_append(cmd, "http://www.foo.com/bar.html?baz=yes");
+ * each parameter appended is one argument, and it gets escaped, quoted, and
+ * appended with a preceeding space. The first is the command off course.
+ */
+
+struct _ecore_exe_dead_exe
+{
+ pid_t pid;
+ char *cmd;
+};
+
+static inline void _ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags);
+static int _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags);
+static int _ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static void _ecore_exe_flush(Ecore_Exe * exe);
+static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev);
+static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid);
+static int _ecore_exe_make_sure_its_dead(void *data);
+static int _ecore_exe_make_sure_its_really_dead(void *data);
+static Ecore_Exe_Event_Add *_ecore_exe_event_add_new(void);
+static void _ecore_exe_event_add_free(void *data, void *ev);
+static void _ecore_exe_dead_attach(Ecore_Exe *exe);
+
+EAPI int ECORE_EXE_EVENT_ADD = 0;
+EAPI int ECORE_EXE_EVENT_DEL = 0;
+EAPI int ECORE_EXE_EVENT_DATA = 0;
+EAPI int ECORE_EXE_EVENT_ERROR = 0;
+
+static Ecore_Exe *exes = NULL;
+static const char *shell = NULL;
+
+/* FIXME: This errno checking stuff should be put elsewhere for everybody to use.
+ * For now it lives here though, just to make testing easier.
+ */
+static int _ecore_exe_check_errno(int result, const char *file, int line);
+
+#define E_IF_NO_ERRNO(result, foo, ok) \
+ while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \
+ if (ok)
+
+#define E_NO_ERRNO(result, foo, ok) \
+ while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)) == -1) sleep(1)
+
+#define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \
+ if (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)))
+
+static int
+_ecore_exe_check_errno(int result, const char *file, int line)
+{
+ int saved_errno = errno;
+
+ if (result == -1)
+ {
+ perror("*** errno reports ");
+/* What is currently supported -
+ *
+ * pipe
+ * EFAULT Argument is not valid.
+ * EMFILE Too many file descriptors used by process.
+ * ENFILE Too many open files by system.
+ * read
+ * EAGAIN No data now, try again.
+ * EBADF This is not an fd that can be read.
+ * EFAULT This is not a valid buffer.
+ * EINTR Interupted by signal, try again.
+ * EINVAL This is not an fd that can be read.
+ * EIO I/O error.
+ * EISDIR This is a directory, and cannot be read.
+ * others Depending on what sort of thing we are reading from.
+ * close
+ * EBADF This is not an fd that can be closed.
+ * EINTR Interupted by signal, try again.
+ * EIO I/O error.
+ * dup2
+ * EBADF This is not an fd that can be dup2'ed.
+ * EBUSY Race condition between open() and dup()
+ * EINTR Interupted by signal, try again.
+ * EMFILE Too many file descriptors used by process.
+ * fcntl
+ * EACCES, EAGAIN Locked or mapped by something else, try again later.
+ * EBADF This is not an fd that can be fcntl'ed.
+ * EDEADLK This will cause a deadlock.
+ * EFAULT This is not a valid lock.
+ * EINTR Interupted by signal, try again.
+ * EINVAL This is not a valid arg.
+ * EMFILE Too many file descriptors used by process.
+ * ENOLCK Problem getting a lock.
+ * EPERM Not allowed to do that.
+ * fsync
+ * EBADF This is not an fd that is open for writing.
+ * EINVAL, EROFS This is not an fd that can be fsynced.
+ * EIO I/O error.
+ *
+ * How to use it -
+ * int ok = 0;
+ * int result;
+ *
+ * E_IF_NO_ERRNO(result, foo(bar), ok)
+ * {
+ * E_IF_NO_ERRNO_NOLOOP(result, foo(bar), ok)
+ * {
+ * }
+ * }
+ *
+ * if (!ok)
+ * {
+ * // Something failed, cleanup.
+ * }
+ */
+ switch (saved_errno)
+ {
+ case EACCES:
+ case EAGAIN:
+ case EINTR:
+ { /* Not now, try later. */
+ ERR("*** Must try again in %s @%u.", file, line);
+ result = -1;
+ break;
+ }
+ case EMFILE:
+ case ENFILE:
+ case ENOLCK:
+ { /* Low on resources. */
+ ERR("*** Low on resources in %s @%u.", file,
+ line);
+ result = 0;
+ break;
+ }
+ case EIO:
+ { /* I/O error. */
+ ERR("*** I/O error in %s @%u.", file, line);
+ result = 0;
+ break;
+ }
+ case EFAULT:
+ case EBADF:
+ case EINVAL:
+ case EROFS:
+ case EISDIR:
+ case EDEADLK:
+ case EPERM:
+ case EBUSY:
+ { /* Programmer fucked up. */
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Now go fix your code in %s @%u. Tut tut tut!",
+ file, line);
+ result = 0;
+ break;
+ }
+ default:
+ { /* Unsupported errno code, please add this one. */
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Unsupported errno code %d, please add this one.\n"
+ "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!",
+ saved_errno, __FILE__, __LINE__, file, line);
+ result = 0;
+ break;
+ }
+ }
+ }
+ else /* Everything is fine. */
+ result = 1;
+
+ errno = saved_errno;
+ return result;
+}
+
+/**
+ * @defgroup Ecore_Exe_Basic_Group Process Spawning Functions
+ *
+ * Functions that deal with spawned processes.
+ */
+
+static int run_pri = ECORE_EXE_PRIORITY_INHERIT;
+
+/**
+ * Sets the priority at which to launch processes
+ *
+ * This sets the priority of processes run by ecore_exe_run() and
+ * ecore_exe_pipe_run().
+ * @li On Windows, the child process is created by default with the
+ * #ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling
+ * process is in #ECORE_EXE_WIN32_PRIORITY_IDLE or
+ * #ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the
+ * child process inherits this priority.
+ * @li On other platforms, if set to #ECORE_EXE_PRIORITY_INHERIT child
+ * processes inherits the priority of their parent. This is the default.
+ *
+ * @param pri value a Ecore_Exe_Win32_Priority value on Windows, -20
+ * to 19 or ECORE_EXE_PRIORITY_INHERIT on other OS.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI void
+ecore_exe_run_priority_set(int pri)
+{
+ run_pri = pri;
+}
+
+/**
+ * Gets the priority at which to launch processes
+ *
+ * This gets ths priority of launched processes. See
+ * ecore_exe_run_priority_set() for details. This just returns the value set
+ * by this call.
+ *
+ * @return the value set by ecore_exe_run_priority_set()
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI int
+ecore_exe_run_priority_get(void)
+{
+ return run_pri;
+}
+
+/**
+ * Spawns a child process.
+ *
+ * This is now just a thin wrapper around ecore_exe_pipe_run()
+ *
+ * @param exe_cmd The command to run with @c /bin/sh.
+ * @param data Data to attach to the returned process handle.
+ * @return A process handle to the spawned process.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI Ecore_Exe *
+ecore_exe_run(const char *exe_cmd, const void *data)
+{
+/* I'm just being paranoid again, leaving in the original code in case there is a problem. */
+#if 0
+ Ecore_Exe *exe;
+ pid_t pid;
+
+ if (!exe_cmd)
+ return NULL;
+ pid = fork();
+ if (pid)
+ {
+ exe = calloc(1, sizeof(Ecore_Exe));
+ if (!exe)
+ {
+ kill(pid, SIGKILL);
+ return NULL;
+ }
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
+ exe->pid = pid;
+ exe->data = (void *)data;
+ exe->cmd = strdup(exe_cmd);
+ exes = _ecore_list2_append(exes, exe);
+ return exe;
+ }
+ _ecore_exe_exec_it(exe_cmd, 0);
+ exit(127);
+ return NULL;
+#else
+ return ecore_exe_pipe_run(exe_cmd, 0, data);
+#endif
+}
+
+/**
+ * Spawns a child process with its stdin/out available for communication.
+ *
+ * This function forks and runs the given command using @c /bin/sh.
+ *
+ * Note that the process handle is only valid until a child process
+ * terminated event is received. After all handlers for the child process
+ * terminated event have been called, the handle will be freed by Ecore.
+ *
+ * This function does the same thing as ecore_exe_run(), but also makes the
+ * standard in and/or out as well as stderr from the child process available
+ * for reading or writing. To write use ecore_exe_send(). To read listen to
+ * ECORE_EXE_EVENT_DATA or ECORE_EXE_EVENT_ERROR events (set up handlers).
+ * Ecore may buffer read and error data until a newline character if asked
+ * for with the @p flags. All data will be included in the events (newlines
+ * will be replaced with NULLS if line buffered). ECORE_EXE_EVENT_DATA events
+ * will only happen if the process is run with ECORE_EXE_PIPE_READ enabled
+ * in the flags. The same with the error version. Writing will only be
+ * allowed with ECORE_EXE_PIPE_WRITE enabled in the flags.
+ *
+ * @param exe_cmd The command to run with @c /bin/sh.
+ * @param flags The flag parameters for how to deal with inter-process I/O
+ * @param data Data to attach to the returned process handle.
+ * @return A process handle to the spawned process.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI Ecore_Exe *
+ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
+{
+ Ecore_Exe *exe = NULL;
+ int statusPipe[2] = { -1, -1 };
+ int errorPipe[2] = { -1, -1 };
+ int readPipe[2] = { -1, -1 };
+ int writePipe[2] = { -1, -1 };
+ int n = 0;
+ int ok = 1;
+ int result;
+
+ if (!exe_cmd) return NULL;
+ exe = calloc(1, sizeof(Ecore_Exe));
+ if (exe == NULL) return NULL;
+
+ if ((flags & ECORE_EXE_PIPE_AUTO) && (!(flags & ECORE_EXE_PIPE_ERROR))
+ && (!(flags & ECORE_EXE_PIPE_READ)))
+ /* We need something to auto pipe. */
+ flags |= ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR;
+
+ exe->child_fd_error = -1;
+ exe->child_fd_read = -1;
+ exe->child_fd_write = -1;
+ exe->child_fd_error_x = -1;
+ exe->child_fd_read_x = -1;
+ exe->child_fd_write_x = -1;
+
+ /* Create some pipes. */
+ if (ok)
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)
+ {
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_ERROR))
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)
+ {
+ exe->child_fd_error = errorPipe[0];
+ exe->child_fd_error_x = errorPipe[1];
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_READ))
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok)
+ {
+ exe->child_fd_read = readPipe[0];
+ exe->child_fd_read_x = readPipe[1];
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_WRITE))
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok)
+ {
+ exe->child_fd_write = writePipe[1];
+ exe->child_fd_write_x = writePipe[0];
+ }
+ }
+ if (ok)
+ {
+ pid_t pid = 0;
+ volatile int vfork_exec_errno = 0;
+
+ /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */
+ /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */
+ pid = fork();
+
+ if (pid == -1)
+ {
+ ERR("Failed to fork process");
+ pid = 0;
+ }
+ else if (pid == 0) /* child */
+ {
+ if (run_pri != ECORE_EXE_PRIORITY_INHERIT)
+ {
+ if ((run_pri >= -20) && (run_pri <= 19))
+ setpriority(PRIO_PROCESS, 0, run_pri);
+ }
+ /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the
+ * second pipe if it's open. On the other hand, there was the
+ * Great FD Leak Scare of '06, so let's be paranoid. */
+ if (ok && (flags & ECORE_EXE_PIPE_ERROR))
+ {
+ E_NO_ERRNO(result, close(STDERR_FILENO), ok);
+ E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok);
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_READ))
+ {
+ E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
+ E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok);
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_WRITE))
+ {
+ E_NO_ERRNO(result, close(STDIN_FILENO), ok);
+ E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok);
+ }
+
+ if (ok)
+ {
+ /* Setup the status pipe. */
+ E_NO_ERRNO(result, close(statusPipe[0]), ok);
+ E_IF_NO_ERRNO(result, fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC), ok) /* close on exec shows sucess */
+ {
+ /* Run the actual command. */
+ _ecore_exe_exec_it(exe_cmd, flags); /* no return */
+ }
+ }
+
+ /* Something went 'orribly wrong. */
+ vfork_exec_errno = errno;
+
+ /* Close the pipes. */
+ if (flags & ECORE_EXE_PIPE_ERROR)
+ E_NO_ERRNO(result, close(errorPipe[1]), ok);
+ if (flags & ECORE_EXE_PIPE_READ)
+ E_NO_ERRNO(result, close(readPipe[1]), ok);
+ if (flags & ECORE_EXE_PIPE_WRITE)
+ E_NO_ERRNO(result, close(writePipe[0]), ok);
+ E_NO_ERRNO(result, close(statusPipe[1]), ok);
+
+ _exit(-1);
+ }
+ else /* parent */
+ {
+ /* Close the unused pipes. */
+ E_NO_ERRNO(result, close(statusPipe[1]), ok);
+
+ /* FIXME: after having a good look at the current e fd
+ * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
+ /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
+ * which is also linux specific so we probably don't want to
+ * do this as long as select() is working fine. the only time
+ * we really want to think of SIGIO async IO is when it all
+ * actually works basically everywhere and we can turn all
+ * IO into DMA async activities (i.e. you do a read() then
+ * the read is complete not on return but when you get a
+ * SIGIO - the read() just starts the transfer and it is
+ * completed in the background by DMA (or whatever mechanism
+ * the kernel choses)) */
+
+ /* Wait for it to start executing. */
+ /* FIXME: this doesn't seem very nice - we sit and block
+ * waiting on a child process... even though it's just
+ * the segment between the fork() and the exec) it just feels
+ * wrong */
+ for (;;)
+ {
+ char buf;
+
+ E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok);
+ if (result == 0)
+ {
+ if (vfork_exec_errno != 0)
+ {
+ n = vfork_exec_errno;
+ ERR("Could not start \"%s\"", exe_cmd);
+ pid = 0;
+ }
+ break;
+ }
+ }
+
+ /* Close the status pipe. */
+ E_NO_ERRNO(result, close(statusPipe[0]), ok);
+ }
+
+ if (pid)
+ {
+ /* Setup the exe structure. */
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
+ exe->start_bytes = -1;
+ exe->end_bytes = -1;
+ exe->start_lines = -1;
+ exe->end_lines = -1;
+ exe->pid = pid;
+ exe->flags = flags;
+ exe->data = (void *)data;
+ if ((exe->cmd = strdup(exe_cmd)))
+ {
+ if (flags & ECORE_EXE_PIPE_ERROR)
+ { /* Setup the error stuff. */
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_error, F_SETFL,
+ O_NONBLOCK), ok) {}
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_error, F_SETFD,
+ FD_CLOEXEC), ok) {}
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_error_x, F_SETFD,
+ FD_CLOEXEC), ok) {}
+ {
+ exe->error_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_error,
+ ECORE_FD_READ,
+ _ecore_exe_data_error_handler,
+ exe, NULL, NULL);
+ if (exe->error_fd_handler == NULL)
+ ok = 0;
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_READ))
+ { /* Setup the read stuff. */
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_read, F_SETFL,
+ O_NONBLOCK), ok) {}
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_read, F_SETFD,
+ FD_CLOEXEC), ok) {}
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_read_x, F_SETFD,
+ FD_CLOEXEC), ok) {}
+ {
+ exe->read_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_read,
+ ECORE_FD_READ,
+ _ecore_exe_data_read_handler,
+ exe, NULL, NULL);
+ if (exe->read_fd_handler == NULL)
+ ok = 0;
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_WRITE))
+ { /* Setup the write stuff. */
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_write, F_SETFL,
+ O_NONBLOCK), ok) {}
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_write, F_SETFD,
+ FD_CLOEXEC), ok) {}
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_write_x, F_SETFD,
+ FD_CLOEXEC), ok) {}
+ {
+ exe->write_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_write,
+ ECORE_FD_WRITE,
+ _ecore_exe_data_write_handler,
+ exe, NULL, NULL);
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
+ else
+ ok = 0;
+ }
+ }
+
+ exes = (Ecore_Exe *) eina_inlist_append(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
+ n = 0;
+ }
+ else
+ ok = 0;
+ }
+ else
+ ok = 0;
+ }
+
+ if (!ok)
+ { /* Something went wrong, so pull down everything. */
+ if (exe->pid) ecore_exe_terminate(exe);
+ IF_FN_DEL(ecore_exe_free, exe);
+ }
+ else
+ {
+ Ecore_Exe_Event_Add *e;
+
+ e = _ecore_exe_event_add_new();
+ e->exe = exe;
+ if (e) /* Send the event. */
+ ecore_event_add(ECORE_EXE_EVENT_ADD, e,
+ _ecore_exe_event_add_free, NULL);
+ /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */
+ }
+
+ errno = n;
+ return exe;
+}
+
+/**
+ * Defines a function to be called before really freeing the handle data.
+ *
+ * This might be useful for language bindings such as Python and Perl
+ * that need to deallocate wrappers associated with this handle.
+ *
+ * This handle should never be modified by this call. It should be
+ * considered informative only. All getters are valid when the given
+ * function is called back.
+ *
+ * @param exe The child process to attach the pre_free function.
+ * @param func The function to call before @a exe is freed.
+ */
+EAPI void
+ecore_exe_callback_pre_free_set(Ecore_Exe *exe, void (*func)(void *data, const Ecore_Exe *exe))
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_callback_pre_free_set");
+ return;
+ }
+ exe->pre_free_cb = func;
+}
+
+/**
+ * Sends data to the given child process which it recieves on stdin.
+ *
+ * This function writes to a child processes standard in, with unlimited
+ * buffering. This call will never block. It may fail if the system runs out
+ * of memory.
+ *
+ * @param exe The child process to send to
+ * @param data The data to send
+ * @param size The size of the data to send, in bytes
+ * @return EINA_TRUE if successful, EINA_FALSE on failure.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI Eina_Bool
+ecore_exe_send(Ecore_Exe * exe, const void *data, int size)
+{
+ void *buf;
+
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send");
+ return 0;
+ }
+
+ if (exe->close_stdin)
+ {
+ ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
+ exe, size, data);
+ return 0;
+ }
+
+ if (exe->child_fd_write == -1)
+ {
+ ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
+ "Cannot send %d bytes from %p", exe, size, data);
+ return 0;
+ }
+
+ buf = realloc(exe->write_data_buf, exe->write_data_size + size);
+ if (buf == NULL) return 0;
+
+ exe->write_data_buf = buf;
+ memcpy((char *)exe->write_data_buf + exe->write_data_size, data, size);
+ exe->write_data_size += size;
+
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
+
+ return 1;
+}
+
+/**
+ * The stdin of the given child process will close when the write buffer is empty.
+ *
+ * @param exe The child process
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI void
+ecore_exe_close_stdin(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_close_stdin");
+ return;
+ }
+ exe->close_stdin = 1;
+}
+
+/**
+ * Sets the auto pipe limits for the given process handle. On Windows
+ * this function does nothing.
+ *
+ * @param exe The given process handle.
+ * @param start_bytes limit of bytes at start of output to buffer.
+ * @param end_bytes limit of bytes at end of output to buffer.
+ * @param start_lines limit of lines at start of output to buffer.
+ * @param end_lines limit of lines at end of output to buffer.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI void
+ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int start_lines, int end_lines)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_auto_limits_set");
+ return;
+ }
+ /* FIXME: sanitize the input. */
+ exe->start_bytes = start_bytes;
+ exe->end_bytes = end_bytes;
+ exe->start_lines = start_lines;
+ exe->end_lines = end_lines;
+
+ /* FIXME: get this can of worms working.
+ *
+ * capture stderr & stdout internally
+ *
+ * raster and onefang keep moving the goal posts on this one. It started out as
+ * "show users the error output if an exe fails" and is rapidly approaching
+ * "alternative method of getting the data, poll vs event driven". Some serious
+ * thinking needs to be applied to this. Do we really want to go that far? If
+ * so, we should change the names. The basic design will probably remain the
+ * same which ever way we go. The constant goal post moving is probably due to
+ * generic design methods leading to feature creep as we inspired each other to
+ * more generic designs. It does seem like the closer we get to poll driven,
+ * the more issues and corner cases there are.
+ *
+ * Instead of doing the usual register an event handler thing, we are ecore_exe,
+ * we can take some short cuts. Don't send the events, just leave the exe buffers
+ * as is until the user asks for them, then return the event.
+ *
+ * start = 0, end = 0; clogged arteries get flushed, everything is ignored.
+ * start = -1, end = -1; clogged arteries get transferred to internal buffers. Actually, either == -1 means buffer everything.
+ * start = X, end = 0; buffer first X out of clogged arteries, flush and ignore rest.
+ * start = 0, end = X; circular buffer X
+ * start = X, end = Y; buffer first X out of clogged arteries, circular buffer Y from beginning.
+ *
+ * bytes vs lines, which ever one reaches the limit first.
+ * Before we go beyond the start+end limit, leave the end buffer empty, and store both in the start buffer, coz they overlap.
+ * After we pass the the start+end limit, insert "\n...\n" at the end of the start buffer, copy the rest to the end buffer, then store in the end buffer.
+ *
+ * Other issues -
+ * Spank programmer for polling data if polling is not turned on.
+ * Spank programmer for setting up event callbacks if polling is turned on.
+ * Spank programmer for freeing the event data if it came from the event system, as that autofrees.
+ * Spank the programmer if they try to set the limits bigger than what has been gathered & ignored already, coz they just lost data.
+ * Spank onefang and raster for opening this can of worms.
+ * Should we have seperate out/err limits?
+ * Should we remove from the internal buffer the data that was delivered already?
+ * If so, what to do about limits, start, and end? They could loose their meaning.
+ */
+}
+
+/**
+ * Gets the auto pipe data for the given process handle
+ *
+ * @param exe The given process handle.
+ * @param flags Is this a ECORE_EXE_PIPE_READ or ECORE_EXE_PIPE_ERROR?
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI Ecore_Exe_Event_Data *
+ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
+{
+ Ecore_Exe_Event_Data *e = NULL;
+ int is_buffered = 0;
+ unsigned char *inbuf;
+ int inbuf_num;
+
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_event_data_get");
+ return NULL;
+ }
+
+ /* Sort out what sort of event we are. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ flags = ECORE_EXE_PIPE_READ;
+ if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED)
+ is_buffered = 1;
+ }
+ else
+ {
+ flags = ECORE_EXE_PIPE_ERROR;
+ if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED)
+ is_buffered = 1;
+ }
+
+ /* Get the data. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ inbuf = exe->read_data_buf;
+ inbuf_num = exe->read_data_size;
+ exe->read_data_buf = NULL;
+ exe->read_data_size = 0;
+ }
+ else
+ {
+ inbuf = exe->error_data_buf;
+ inbuf_num = exe->error_data_size;
+ exe->error_data_buf = NULL;
+ exe->error_data_size = 0;
+ }
+
+ e = calloc(1, sizeof(Ecore_Exe_Event_Data));
+ if (e)
+ {
+ e->exe = exe;
+ e->data = inbuf;
+ e->size = inbuf_num;
+
+ if (is_buffered)
+ { /* Deal with line buffering. */
+ int max = 0;
+ int count = 0;
+ int i;
+ int last = 0;
+ char *c;
+
+ c = (char *)inbuf;
+ for (i = 0; i < inbuf_num; i++) /* Find the lines. */
+ {
+ if (inbuf[i] == '\n')
+ {
+ if (count >= max)
+ {
+ /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
+ max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
+ e->lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
+ }
+ /* raster said to leave the line endings as line endings, however -
+ * This is line buffered mode, we are not dealing with binary here, but lines.
+ * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
+ * Thus the user is most likely gonna deal with this text as strings.
+ * Thus the user is most likely gonna pass this data to str functions.
+ * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
+ * We are handing them the string length as a convenience.
+ * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
+ * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
+ * Let's make it easy on them to use these as standard C strings.
+ *
+ * onefang is proud to announce that he has just set a new personal record for the
+ * most over documentation of a simple assignment statement. B-)
+ */
+ inbuf[i] = '\0';
+ e->lines[count].line = c;
+ e->lines[count].size = i - last;
+ last = i + 1;
+ c = (char *)&inbuf[last];
+ count++;
+ }
+ }
+ if (count == 0) /* No lines to send, cancel the event. */
+ {
+ _ecore_exe_event_exe_data_free(NULL, e);
+ e = NULL;
+ }
+ else /* NULL terminate the array, so that people know where the end is. */
+ {
+ e->lines[count].line = NULL;
+ e->lines[count].size = 0;
+ }
+ if (i > last) /* Partial line left over, save it for next time. */
+ {
+ if (e) e->size = last;
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ exe->read_data_size = i - last;
+ exe->read_data_buf = malloc(exe->read_data_size);
+ memcpy(exe->read_data_buf, c, exe->read_data_size);
+ }
+ else
+ {
+ exe->error_data_size = i - last;
+ exe->error_data_buf = malloc(exe->error_data_size);
+ memcpy(exe->error_data_buf, c, exe->error_data_size);
+ }
+ }
+ }
+ }
+
+ return e;
+}
+
+/**
+ * Sets the string tag for the given process handle
+ *
+ * @param exe The given process handle.
+ * @param tag The string tag to set on the process handle.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI void
+ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_set");
+ return;
+ }
+ IF_FREE(exe->tag);
+ if (tag)
+ exe->tag = strdup(tag);
+ else
+ exe->tag = NULL;
+}
+
+/**
+ * Retrieves the tag attached to the given process handle. There is no need to
+ * free it as it just returns the internal pointer value. This value is only
+ * valid as long as the @p exe is valid or until the tag is set to something
+ * else on this @p exe.
+ *
+ * @param exe The given process handle.
+ * @return The string attached to @p exe. It is a handle to existing
+ * internal string and should not be modified, use
+ * ecore_exe_tag_set() to change it. It might be @c NULL.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI const char *
+ecore_exe_tag_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_get");
+ return NULL;
+ }
+ return exe->tag;
+}
+
+/**
+ * Frees the given process handle.
+ *
+ * Note that the process that the handle represents is unaffected by this
+ * function.
+ *
+ * @param exe The given process handle.
+ * @return The data attached to the handle when @ref ecore_exe_run was
+ * called.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI void *
+ecore_exe_free(Ecore_Exe *exe)
+{
+ void *data;
+ int ok = 0;
+ int result;
+
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free");
+ return NULL;
+ }
+
+ data = exe->data;
+
+ if (exe->pre_free_cb)
+ exe->pre_free_cb(data, exe);
+
+ if (exe->doomsday_clock)
+ {
+ struct _ecore_exe_dead_exe *dead;
+
+ ecore_timer_del(exe->doomsday_clock);
+ exe->doomsday_clock = NULL;
+ dead = exe->doomsday_clock_dead;
+ if (dead)
+ {
+ IF_FREE(dead->cmd);
+ free(dead);
+ exe->doomsday_clock_dead = NULL;
+ }
+ }
+ IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
+ IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler);
+ IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler);
+ if (exe->child_fd_write_x != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_write_x), ok);
+ if (exe->child_fd_read_x != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_read_x), ok);
+ if (exe->child_fd_error_x != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_error_x), ok);
+ if (exe->child_fd_write != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_write), ok);
+ if (exe->child_fd_read != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_read), ok);
+ if (exe->child_fd_error != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_error), ok);
+ IF_FREE(exe->write_data_buf);
+ IF_FREE(exe->read_data_buf);
+ IF_FREE(exe->error_data_buf);
+ IF_FREE(exe->cmd);
+
+ exes = (Ecore_Exe *) eina_inlist_remove(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
+ IF_FREE(exe->tag);
+ free(exe);
+ return data;
+}
+
+/**
+ * Frees the given event data.
+ *
+ * @param e The given event data.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI void
+ecore_exe_event_data_free(Ecore_Exe_Event_Data *e)
+{
+ if (!e) return;
+ IF_FREE(e->lines);
+ IF_FREE(e->data);
+ free(e);
+}
+
+/**
+ * Retrieves the process ID of the given spawned process.
+ * @param exe Handle to the given spawned process.
+ * @return The process ID on success. @c -1 otherwise.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI pid_t
+ecore_exe_pid_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pid_get");
+ return -1;
+ }
+ return exe->pid;
+}
+
+/**
+ * Retrieves the command of the given spawned process.
+ * @param exe Handle to the given spawned process.
+ * @return The command on success. NULL otherwise. This string is the
+ * pointer to the internal value and must not be modified in
+ * any way.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI const char *
+ecore_exe_cmd_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_cmd_get");
+ return NULL;
+ }
+ return exe->cmd;
+}
+
+/**
+ * Retrieves the data attached to the given process handle.
+ * @param exe The given process handle.
+ * @return The data pointer attached to @p exe Given to
+ * ecore_exe_run() or ecore_exe_pipe_run()
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI void *
+ecore_exe_data_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
+ return NULL;
+ }
+ return exe->data;
+}
+
+/**
+ * Retrieves the flags attached to the given process handle.
+ * @param exe The given process handle.
+ * @return The flags attached to @p exe.
+ * @ingroup Ecore_Exe_Basic_Group
+ */
+EAPI Ecore_Exe_Flags
+ecore_exe_flags_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
+ return 0;
+ }
+ return exe->flags;
+}
+
+/**
+ * @defgroup Ecore_Exe_Signal_Group Spawned Process Signal Functions
+ *
+ * Functions that send signals to spawned processes.
+ */
+
+/**
+ * Pauses the given process by sending it a @c SIGSTOP signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_pause(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause");
+ return;
+ }
+ kill(exe->pid, SIGSTOP);
+}
+
+/**
+ * Continues the given paused process by sending it a @c SIGCONT signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_continue(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_continue");
+ return;
+ }
+ kill(exe->pid, SIGCONT);
+}
+
+/**
+ * Sends the given spawned process a interrupt (@c SIGINT) signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_interrupt(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_interrupt");
+ return;
+ }
+ _ecore_exe_dead_attach(exe);
+ kill(exe->pid, SIGINT);
+}
+
+/**
+ * Sends the given spawned process a quit (@c SIGQUIT) signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_quit(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_quit");
+ return;
+ }
+ _ecore_exe_dead_attach(exe);
+ kill(exe->pid, SIGQUIT);
+}
+
+/**
+ * Sends the given spawned process a terminate (@c SIGTERM) signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_terminate(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_terminate");
+ return;
+ }
+ _ecore_exe_dead_attach(exe);
+ INF("Sending TERM signal to %s (%d).", exe->cmd, exe->pid);
+ kill(exe->pid, SIGTERM);
+}
+
+/**
+ * Kills the given spawned process by sending it a @c SIGKILL signal.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_kill(Ecore_Exe *exe)
+{
+ struct _ecore_exe_dead_exe *dead;
+
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill");
+ return;
+ }
+
+ dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
+ if (dead)
+ {
+ dead->pid = exe->pid;
+ dead->cmd = strdup(exe->cmd);
+ IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
+ exe->doomsday_clock =
+ ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
+ }
+
+ INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid);
+ kill(exe->pid, SIGKILL);
+}
+
+/**
+ * Sends a @c SIGUSR signal to the given spawned process.
+ * @param exe Process handle to the given process.
+ * @param num The number user signal to send. Must be either 1 or 2, or
+ * the signal will be ignored.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_signal(Ecore_Exe *exe, int num)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal");
+ return;
+ }
+ if (num == 1)
+ kill(exe->pid, SIGUSR1);
+ else if (num == 2)
+ kill(exe->pid, SIGUSR2);
+}
+
+/**
+ * Sends a @c SIGHUP signal to the given spawned process.
+ * @param exe Process handle to the given process.
+ * @ingroup Ecore_Exe_Signal_Group
+ */
+EAPI void
+ecore_exe_hup(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup");
+ return;
+ }
+ kill(exe->pid, SIGHUP);
+}
+
+static Ecore_Exe *
+_ecore_exe_is_it_alive(pid_t pid)
+{
+ Ecore_Exe *exe = NULL;
+
+ /* FIXME: There is no nice, safe, OS independant way to tell if a
+ * particular PID is still alive. I have written code to do so
+ * for my urunlevel busybox applet (http://urunlevel.sourceforge.net/),
+ * but it's for linux only, and still not guaranteed.
+ *
+ * So for now, we just check that a valid Ecore_Exe structure
+ * exists for it. Even that is not a guarantee, as the structure
+ * can be freed without killing the process.
+ *
+ * I think we can safely put exe's into two categories, those users
+ * that care about the life of the exe, and the run and forget type.
+ * The run and forget type starts up the exe, then free's the
+ * Ecore_Exe structure straight away. They can never call any of
+ * the functions that can call this, so we don't worry about them.
+ *
+ * Those user's that care about the life of exe's will keep the
+ * Ecore_Exe structure around, terminate them eventually, or
+ * register for exit events. For these ones the assumption
+ * that valid Ecore_Exe struct == live exe is almost valid.
+ *
+ * I will probably copy my urunlevel code into here someday.
+ */
+ exe = _ecore_exe_find(pid);
+ if (exe)
+ {
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ exe = NULL;
+ }
+
+ return exe;
+}
+
+static int
+_ecore_exe_make_sure_its_dead(void *data)
+{
+ struct _ecore_exe_dead_exe *dead;
+
+ dead = data;
+ if (dead)
+ {
+ Ecore_Exe *exe = NULL;
+
+ if ((exe = _ecore_exe_is_it_alive(dead->pid)) != NULL)
+ {
+ if (dead->cmd)
+ INF("Sending KILL signal to alledgedly dead %s (%d).",
+ dead->cmd, dead->pid);
+ else
+ INF("Sending KILL signal to alledgedly dead PID %d.",
+ dead->pid);
+ exe->doomsday_clock =
+ ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead,
+ dead);
+ kill(dead->pid, SIGKILL);
+ }
+ else
+ {
+ IF_FREE(dead->cmd);
+ free(dead);
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_exe_make_sure_its_really_dead(void *data)
+{
+ struct _ecore_exe_dead_exe *dead;
+
+ dead = data;
+ if (dead)
+ {
+ Ecore_Exe *exe = NULL;
+
+ if ((exe = _ecore_exe_is_it_alive(dead->pid)) != NULL)
+ {
+ ERR("RUN! The zombie wants to eat your brains! And your CPU!");
+ if (dead->cmd)
+ INF("%s (%d) is not really dead.", dead->cmd, dead->pid);
+ else
+ INF("PID %d is not really dead.", dead->pid);
+ exe->doomsday_clock = NULL;
+ }
+ IF_FREE(dead->cmd);
+ free(dead);
+ }
+ return 0;
+}
+
+void
+_ecore_exe_init(void)
+{
+ ECORE_EXE_EVENT_ADD = ecore_event_type_new();
+ ECORE_EXE_EVENT_DEL = ecore_event_type_new();
+ ECORE_EXE_EVENT_DATA = ecore_event_type_new();
+ ECORE_EXE_EVENT_ERROR = ecore_event_type_new();
+}
+
+void
+_ecore_exe_shutdown(void)
+{
+ while (exes)
+ ecore_exe_free(exes);
+}
+
+Ecore_Exe *
+_ecore_exe_find(pid_t pid)
+{
+ Ecore_Exe *exe;
+
+ EINA_INLIST_FOREACH(exes, exe)
+ {
+ if (exe->pid == pid)
+ return exe;
+ }
+ return NULL;
+}
+
+Ecore_Timer *
+_ecore_exe_doomsday_clock_get(Ecore_Exe *exe)
+{
+ return exe->doomsday_clock;
+}
+
+void
+_ecore_exe_doomsday_clock_set(Ecore_Exe *exe, Ecore_Timer *dc)
+{
+ exe->doomsday_clock = dc;
+}
+
+static inline void
+_ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags)
+{
+ char use_sh = 1;
+ char *buf = NULL;
+ char **args = NULL;
+ int save_errno = 0;
+
+ /* So what is this doing?
+ *
+ * We are trying to avoid wrapping the exe call with /bin/sh -c.
+ * We conservatively search for certain shell meta characters,
+ * If we don't find them, we can call the exe directly.
+ */
+ if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#"))
+ {
+ char *token;
+ char pre_command = 1;
+ int num_tokens = 0;
+
+ if (!(buf = strdup(exe_cmd)))
+ return;
+
+ token = strtok(buf, " \t\n\v");
+ while (token)
+ {
+ if (token[0] == '~')
+ break;
+ if (pre_command)
+ {
+ if (token[0] == '[')
+ break;
+ if (strchr(token, '='))
+ break;
+ else
+ pre_command = 0;
+ }
+ num_tokens++;
+ token = strtok(NULL, " \t\n\v");
+ }
+ IF_FREE(buf);
+ if ((!token) && (num_tokens))
+ {
+ int i = 0;
+
+ if (!(buf = strdup(exe_cmd)))
+ return;
+
+ token = strtok(buf, " \t\n\v");
+ use_sh = 0;
+ if (!(args = (char **)calloc(num_tokens + 1, sizeof(char *))))
+ {
+ IF_FREE(buf);
+ return;
+ }
+ for (i = 0; i < num_tokens; i++)
+ {
+ if (token)
+ args[i] = token;
+ token = strtok(NULL, " \t\n\v");
+ }
+ args[num_tokens] = NULL;
+ }
+ }
+
+ if (!(flags & ECORE_EXE_NOT_LEADER)) setsid();
+ if ((flags & ECORE_EXE_USE_SH))
+ {
+ errno = 0;
+ execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
+ }
+ else if (use_sh)
+ { /* We have to use a shell to run this. */
+ if (shell == NULL)
+ { /* Find users preferred shell. */
+ shell = getenv("SHELL");
+ if (shell == 0)
+ shell = "/bin/sh";
+ }
+ errno = 0;
+ execl(shell, shell, "-c", exe_cmd, (char *)NULL);
+ }
+ else
+ { /* We can run this directly. */
+ errno = 0;
+ execvp(args[0], args);
+ }
+
+ save_errno = errno;
+ IF_FREE(buf);
+ IF_FREE(args);
+ errno = save_errno;
+ return;
+}
+
+static int
+_ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags)
+{
+ Ecore_Exe *exe;
+ int child_fd;
+ int event_type;
+
+ exe = data;
+
+ /* Sort out what sort of handler we are. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ flags = ECORE_EXE_PIPE_READ;
+ event_type = ECORE_EXE_EVENT_DATA;
+ child_fd = exe->child_fd_read;
+ }
+ else
+ {
+ flags = ECORE_EXE_PIPE_ERROR;
+ event_type = ECORE_EXE_EVENT_ERROR;
+ child_fd = exe->child_fd_error;
+ }
+
+ if ((fd_handler)
+ && (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)))
+ {
+ unsigned char *inbuf;
+ int inbuf_num;
+
+ /* Get any left over data from last time. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ inbuf = exe->read_data_buf;
+ inbuf_num = exe->read_data_size;
+ exe->read_data_buf = NULL;
+ exe->read_data_size = 0;
+ }
+ else
+ {
+ inbuf = exe->error_data_buf;
+ inbuf_num = exe->error_data_size;
+ exe->error_data_buf = NULL;
+ exe->error_data_size = 0;
+ }
+
+ for (;;)
+ {
+ int num, lost_exe;
+ char buf[READBUFSIZ];
+
+ lost_exe = 0;
+ errno = 0;
+ if ((num = read(child_fd, buf, READBUFSIZ)) < 1)
+ /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE
+ * (currently 64k) to inbuf, use that instead of buf, and
+ * save ourselves a memcpy(). */
+ {
+ lost_exe = ((errno == EIO) ||
+ (errno == EBADF) ||
+ (errno == EPIPE) ||
+ (errno == EINVAL) || (errno == ENOSPC));
+ if ((errno != EAGAIN) && (errno != EINTR))
+ perror("_ecore_exe_generic_handler() read problem ");
+ }
+ if (num > 0)
+ { /* data got read. */
+ inbuf = realloc(inbuf, inbuf_num + num);
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
+ }
+ else
+ { /* No more data to read. */
+ if (inbuf)
+ {
+ Ecore_Exe_Event_Data *e;
+
+ /* Stash the data away for later. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ exe->read_data_buf = inbuf;
+ exe->read_data_size = inbuf_num;
+ }
+ else
+ {
+ exe->error_data_buf = inbuf;
+ exe->error_data_size = inbuf_num;
+ }
+
+ if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
+ {
+ e = ecore_exe_event_data_get(exe, flags);
+ if (e) /* Send the event. */
+ ecore_event_add(event_type, e,
+ _ecore_exe_event_exe_data_free,
+ NULL);
+ }
+ }
+ if (lost_exe)
+ {
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ if (exe->read_data_size)
+ INF("There are %d bytes left unsent from the dead exe %s.",
+ exe->read_data_size, exe->cmd);
+ }
+ else
+ {
+ if (exe->error_data_size)
+ INF("There are %d bytes left unsent from the dead exe %s.",
+ exe->error_data_size, exe->cmd);
+ }
+ /* Thought about this a bit. If the exe has actually
+ * died, this won't do any harm as it must have died
+ * recently and the pid has not had a chance to recycle.
+ * It is also a paranoid catchall, coz the usual ecore_signal
+ * mechenism should kick in. But let's give it a good
+ * kick in the head anyway.
+ */
+ ecore_exe_terminate(exe);
+ }
+ break;
+ }
+ }
+ }
+
+ return 1;
+}
+
+static int
+_ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ return _ecore_exe_data_generic_handler(data, fd_handler,
+ ECORE_EXE_PIPE_ERROR);
+}
+
+static int
+_ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ return _ecore_exe_data_generic_handler(data, fd_handler,
+ ECORE_EXE_PIPE_READ);
+}
+
+static int
+_ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Ecore_Exe *exe;
+
+ exe = data;
+ if ((exe->write_fd_handler) &&
+ (ecore_main_fd_handler_active_get
+ (exe->write_fd_handler, ECORE_FD_WRITE)))
+ _ecore_exe_flush(exe);
+
+ /* If we have sent all there is to send, and we need to close the pipe, then close it. */
+ if ((exe->close_stdin == 1)
+ && (exe->write_data_size == exe->write_data_offset))
+ {
+ int ok = 0;
+ int result;
+
+ INF("Closing stdin for %s", exe->cmd);
+ /* if (exe->child_fd_write != -1) E_NO_ERRNO(result, fsync(exe->child_fd_write), ok); This a) doesn't work, and b) isn't needed. */
+ IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
+ if (exe->child_fd_write != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_write), ok);
+ exe->child_fd_write = -1;
+ IF_FREE(exe->write_data_buf);
+ }
+
+ return 1;
+}
+
+static void
+_ecore_exe_flush(Ecore_Exe *exe)
+{
+ int count;
+
+ /* check whether we need to write anything at all. */
+ if ((exe->child_fd_write == -1) || (!exe->write_data_buf))
+ return;
+ if (exe->write_data_size == exe->write_data_offset)
+ return;
+
+ count = write(exe->child_fd_write,
+ (char *)exe->write_data_buf + exe->write_data_offset,
+ exe->write_data_size - exe->write_data_offset);
+ if (count < 1)
+ {
+ if (errno == EIO || errno == EBADF || errno == EPIPE || errno == EINVAL || errno == ENOSPC) /* we lost our exe! */
+ {
+ ecore_exe_terminate(exe);
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
+ }
+ }
+ else
+ {
+ exe->write_data_offset += count;
+ if (exe->write_data_offset >= exe->write_data_size)
+ { /* Nothing left to write, clean up. */
+ exe->write_data_size = 0;
+ exe->write_data_offset = 0;
+ IF_FREE(exe->write_data_buf);
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
+ }
+ }
+}
+
+static void
+_ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Exe_Event_Data *e;
+
+ e = ev;
+ ecore_exe_event_data_free(e);
+}
+
+static Ecore_Exe_Event_Add *
+_ecore_exe_event_add_new(void)
+{
+ Ecore_Exe_Event_Add *e;
+
+ e = calloc(1, sizeof(Ecore_Exe_Event_Add));
+ return e;
+}
+
+static void
+_ecore_exe_event_add_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Exe_Event_Add *e;
+
+ e = ev;
+ free(e);
+}
+
+void *
+_ecore_exe_event_del_new(void)
+{
+ Ecore_Exe_Event_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Exe_Event_Del));
+ return e;
+}
+
+void
+_ecore_exe_event_del_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Exe_Event_Del *e;
+
+ e = ev;
+ if (e->exe)
+ ecore_exe_free(e->exe);
+ free(e);
+}
+
+static void
+_ecore_exe_dead_attach(Ecore_Exe *exe)
+{
+ struct _ecore_exe_dead_exe *dead;
+
+ if (exe->doomsday_clock_dead) return;
+ dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
+ if (dead)
+ {
+ dead->pid = exe->pid;
+ dead->cmd = strdup(exe->cmd);
+ IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
+ exe->doomsday_clock =
+ ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
+ exe->doomsday_clock_dead = dead;
+ }
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * TODO:
+ * - manage I/O pipes (several ones, and stdin)
+ * - manage SetConsoleCtrlHandler ?
+ * - the child process seems to still run after the DEL event
+ * - add log messages
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <process.h>
+
+#define ECORE_EXE_WIN32_TIMEOUT 3000
+
+typedef enum
+{
+ ECORE_EXE_WIN32_SIGINT,
+ ECORE_EXE_WIN32_SIGQUIT,
+ ECORE_EXE_WIN32_SIGTERM,
+ ECORE_EXE_WIN32_SIGKILL
+} Ecore_Exe_Win32_Signal;
+
+struct _Ecore_Exe
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+
+ HANDLE process2;
+ HANDLE process; /* CloseHandle */
+ HANDLE process_thread;
+ DWORD process_id;
+ DWORD thread_id;
+ void *data;
+ char *tag;
+ char *cmd;
+ Ecore_Exe_Flags flags;
+ Ecore_Exe_Win32_Signal sig;
+ Ecore_Win32_Handler *h_close;
+ struct
+ {
+ HANDLE child_pipe;
+ HANDLE child_pipe_x;
+ Ecore_Pipe *p;
+ HANDLE thread;
+ void *data_buf;
+ int data_size;
+ } pipe_read;
+ struct
+ {
+ HANDLE child_pipe;
+ HANDLE child_pipe_x;
+ HANDLE thread;
+ Ecore_Win32_Handler *h;
+ void *data_buf;
+ int data_size;
+ } pipe_write;
+ struct
+ {
+ HANDLE child_pipe;
+ HANDLE child_pipe_x;
+ Ecore_Pipe *p;
+ HANDLE thread;
+ void *data_buf;
+ int data_size;
+ } pipe_error;
+ Eina_Bool close_stdin : 1;
+ Eina_Bool is_suspended : 1;
+
+ void (*pre_free_cb)(void *data, const Ecore_Exe *exe);
+};
+
+static Ecore_Exe *exes = NULL;
+
+static int _ecore_exe_win32_pipes_set(Ecore_Exe *exe);
+static void _ecore_exe_win32_pipes_close(Ecore_Exe *exe);
+
+static BOOL CALLBACK _ecore_exe_enum_windows_procedure(HWND window, LPARAM data);
+static void _ecore_exe_event_add_free(void *data, void *ev);
+static void _ecore_exe_event_del_free(void *data, void *ev);
+static void _ecore_exe_event_exe_data_free(void *data,
+ void *ev);
+static int _ecore_exe_win32_pipe_thread_generic_cb(void *data, Ecore_Exe_Flags flags);
+static DWORD WINAPI _ecore_exe_win32_pipe_thread_read_cb(void *data);
+static DWORD WINAPI _ecore_exe_win32_pipe_thread_error_cb(void *data);
+static int _ecore_exe_close_cb(void *data, Ecore_Win32_Handler *wh);
+static void _ecore_exe_pipe_read_cb(void *data, void *buf, unsigned int size);
+static int _ecore_exe_pipe_write_cb(void *data, Ecore_Win32_Handler *wh);
+static void _ecore_exe_pipe_error_cb(void *data, void *buf, unsigned int size);
+
+EAPI int ECORE_EXE_EVENT_ADD = 0;
+EAPI int ECORE_EXE_EVENT_DEL = 0;
+EAPI int ECORE_EXE_EVENT_DATA = 0;
+EAPI int ECORE_EXE_EVENT_ERROR = 0;
+
+void
+_ecore_exe_init(void)
+{
+ ECORE_EXE_EVENT_ADD = ecore_event_type_new();
+ ECORE_EXE_EVENT_DEL = ecore_event_type_new();
+ ECORE_EXE_EVENT_DATA = ecore_event_type_new();
+ ECORE_EXE_EVENT_ERROR = ecore_event_type_new();
+}
+
+void
+_ecore_exe_shutdown(void)
+{
+ while (exes)
+ ecore_exe_free(exes);
+}
+
+static int run_pri = NORMAL_PRIORITY_CLASS;
+
+EAPI void
+ecore_exe_run_priority_set(int pri)
+{
+ switch (pri)
+ {
+ case ECORE_EXE_WIN32_PRIORITY_IDLE:
+ run_pri = IDLE_PRIORITY_CLASS;
+ break;
+ case ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL:
+ run_pri = BELOW_NORMAL_PRIORITY_CLASS;
+ break;
+ case ECORE_EXE_WIN32_PRIORITY_NORMAL:
+ run_pri = NORMAL_PRIORITY_CLASS;
+ break;
+ case ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL:
+ run_pri = ABOVE_NORMAL_PRIORITY_CLASS;
+ break;
+ case ECORE_EXE_WIN32_PRIORITY_HIGH:
+ run_pri = HIGH_PRIORITY_CLASS;
+ break;
+ case ECORE_EXE_WIN32_PRIORITY_REALTIME:
+ run_pri = REALTIME_PRIORITY_CLASS;
+ break;
+ default:
+ break;
+ }
+}
+
+EAPI int
+ecore_exe_run_priority_get(void)
+{
+ switch (run_pri)
+ {
+ case IDLE_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_IDLE;
+ case BELOW_NORMAL_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL;
+ case NORMAL_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_NORMAL;
+ case ABOVE_NORMAL_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL;
+ case HIGH_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_HIGH;
+ case REALTIME_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_REALTIME;
+ /* default should not be reached */
+ default:
+ return ECORE_EXE_WIN32_PRIORITY_NORMAL;
+ }
+}
+
+EAPI Ecore_Exe *
+ecore_exe_run(const char *exe_cmd, const void *data)
+{
+ return ecore_exe_pipe_run(exe_cmd, 0, data);
+}
+
+EAPI Ecore_Exe *
+ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ Ecore_Exe_Event_Add *e;
+ Ecore_Exe *exe;
+ char *ret = NULL;
+
+ exe = calloc(1, sizeof(Ecore_Exe));
+ if (!exe)
+ return NULL;
+
+ if ((flags & ECORE_EXE_PIPE_AUTO) && (!(flags & ECORE_EXE_PIPE_ERROR))
+ && (!(flags & ECORE_EXE_PIPE_READ)))
+ /* We need something to auto pipe. */
+ flags |= ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR;
+
+ exe->flags = flags;
+ if (exe->flags & ECORE_EXE_PIPE_READ)
+ if (!_ecore_exe_win32_pipes_set(exe))
+ goto free_exe;
+
+ if (exe->flags & ECORE_EXE_PIPE_WRITE)
+ if (!_ecore_exe_win32_pipes_set(exe))
+ goto close_pipes;
+
+ if (exe->flags & ECORE_EXE_PIPE_ERROR)
+ if (!_ecore_exe_win32_pipes_set(exe))
+ goto close_pipes;
+
+ if ((exe->flags & ECORE_EXE_USE_SH) ||
+ ((ret = strrstr(exe_cmd, ".bat")) && (ret[4] == '\0')))
+ {
+ char buf[PATH_MAX];
+ snprintf(buf, PATH_MAX, "cmd.exe /c %s", exe_cmd);
+ exe->cmd = strdup(buf);
+ }
+ else
+ exe->cmd = strdup(exe_cmd);
+
+ if (!exe->cmd)
+ goto close_pipes;
+
+ ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+
+ ZeroMemory(&si, sizeof(STARTUPINFO));
+ si.cb = sizeof(STARTUPINFO);
+ si.hStdOutput = exe->pipe_read.child_pipe_x;
+ si.hStdInput = exe->pipe_write.child_pipe;
+ si.hStdError = exe->pipe_error.child_pipe_x;
+ si.dwFlags |= STARTF_USESTDHANDLES;
+
+ /* FIXME: gerer la priorite */
+
+ if (!CreateProcess(NULL, exe->cmd, NULL, NULL, EINA_TRUE,
+ run_pri | CREATE_SUSPENDED, NULL, NULL, &si, &pi))
+ goto free_exe_cmd;
+
+ /* be sure that the child process is running */
+ /* FIXME: This does not work if the child is an EFL-based app */
+ /* if (WaitForInputIdle(pi.hProcess, INFINITE) == WAIT_FAILED) */
+ /* goto free_exe_cmd; */
+
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
+ exe->process = pi.hProcess;
+ exe->process_thread = pi.hThread;
+ exe->process_id = pi.dwProcessId;
+ exe->thread_id = pi.dwThreadId;
+ exe->data = (void *)data;
+
+ if (!(exe->process2 = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE | SYNCHRONIZE,
+ EINA_FALSE, pi.dwProcessId)))
+ goto close_thread;
+
+ exe->h_close = ecore_main_win32_handler_add(exe->process2, _ecore_exe_close_cb, exe);
+ if (!exe->h_close) goto close_process2;
+
+ if (ResumeThread(exe->process_thread) == ((DWORD)-1))
+ goto close_process2;
+
+ exes = (Ecore_Exe *)eina_inlist_append(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
+
+ e = (Ecore_Exe_Event_Add *)calloc(1, sizeof(Ecore_Exe_Event_Add));
+ if (!e) goto delete_h_close;
+
+ e->exe = exe;
+ ecore_event_add(ECORE_EXE_EVENT_ADD, e,
+ _ecore_exe_event_add_free, NULL);
+
+ return exe;
+
+ delete_h_close:
+ ecore_main_win32_handler_del(exe->h_close);
+ close_process2:
+ CloseHandle(exe->process2);
+ close_thread:
+ CloseHandle(exe->process_thread);
+ CloseHandle(exe->process);
+ free_exe_cmd:
+ free(exe->cmd);
+ close_pipes:
+ _ecore_exe_win32_pipes_close(exe);
+ free_exe:
+ free(exe);
+ return NULL;
+}
+
+EAPI void
+ecore_exe_callback_pre_free_set(Ecore_Exe *exe, void (*func)(void *data, const Ecore_Exe *exe))
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_callback_pre_free_set");
+ return;
+ }
+ exe->pre_free_cb = func;
+}
+
+EAPI Eina_Bool
+ecore_exe_send(Ecore_Exe *exe, const void *data, int size)
+{
+ void *buf;
+
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send");
+ return 0;
+ }
+
+ if (exe->close_stdin)
+ {
+ ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
+ exe, size, data);
+ return 0;
+ }
+
+ if (!exe->pipe_write.child_pipe)
+ {
+ ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
+ "Cannot send %d bytes from %p", exe, size, data);
+ return 0;
+ }
+
+ buf = realloc(exe->pipe_write.data_buf, exe->pipe_write.data_size + size);
+ if (buf == NULL) return 0;
+
+ exe->pipe_write.data_buf = buf;
+ memcpy((char *)exe->pipe_write.data_buf + exe->pipe_write.data_size, data, size);
+ exe->pipe_write.data_size += size;
+
+ /* if (exe->pipe_write.) */
+ /* ecore_main_fd_handler_active_set(exe->pipe_write.h, ECORE_FD_WRITE); */
+
+ return 1;
+}
+
+EAPI void
+ecore_exe_close_stdin(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_close_stdin");
+ return;
+ }
+ exe->close_stdin = 1;
+}
+
+/* Not used on Windows */
+EAPI void
+ecore_exe_auto_limits_set(Ecore_Exe *exe __UNUSED__, int start_bytes __UNUSED__, int end_bytes __UNUSED__, int start_lines __UNUSED__, int end_lines __UNUSED__)
+{
+}
+
+EAPI Ecore_Exe_Event_Data *
+ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
+{
+ Ecore_Exe_Event_Data *e = NULL;
+ unsigned char *inbuf;
+ int inbuf_num;
+
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_event_data_get");
+ return NULL;
+ }
+
+ /* Sort out what sort of event we are, */
+ /* And get the data. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ inbuf = exe->pipe_read.data_buf;
+ inbuf_num = exe->pipe_read.data_size;
+ exe->pipe_read.data_buf = NULL;
+ exe->pipe_read.data_size = 0;
+ }
+ else
+ {
+ inbuf = exe->pipe_error.data_buf;
+ inbuf_num = exe->pipe_error.data_size;
+ exe->pipe_error.data_buf = NULL;
+ exe->pipe_error.data_size = 0;
+ }
+
+ e = calloc(1, sizeof(Ecore_Exe_Event_Data));
+ if (e)
+ {
+ e->exe = exe;
+ e->data = inbuf;
+ e->size = inbuf_num;
+ }
+
+ return e;
+}
+
+EAPI void
+ecore_exe_event_data_free(Ecore_Exe_Event_Data *e)
+{
+ if (!e) return;
+ IF_FREE(e->lines);
+ IF_FREE(e->data);
+ free(e);
+}
+
+EAPI void *
+ecore_exe_free(Ecore_Exe *exe)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free");
+ return NULL;
+ }
+
+ data = exe->data;
+
+ if (exe->pre_free_cb)
+ exe->pre_free_cb(data, exe);
+
+ CloseHandle(exe->process2);
+ CloseHandle(exe->process_thread);
+ CloseHandle(exe->process);
+ free(exe->cmd);
+ _ecore_exe_win32_pipes_close(exe);
+ exes = (Ecore_Exe *)eina_inlist_remove(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
+ if (exe->tag) free(exe->tag);
+ free(exe);
+
+ return data;
+}
+
+EAPI pid_t
+ecore_exe_pid_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pid_get");
+ return -1;
+ }
+ return exe->process_id;
+}
+
+EAPI void
+ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_set");
+ return;
+ }
+ IF_FREE(exe->tag);
+ if (tag)
+ exe->tag = strdup(tag);
+}
+
+EAPI const char *
+ecore_exe_tag_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_get");
+ return NULL;
+ }
+ return exe->tag;
+}
+
+EAPI const char *
+ecore_exe_cmd_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_cmd_get");
+ return NULL;
+ }
+ return exe->cmd;
+}
+
+EAPI void *
+ecore_exe_data_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
+ return NULL;
+ }
+ return exe->data;
+}
+
+EAPI Ecore_Exe_Flags
+ecore_exe_flags_get(const Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
+ return 0;
+ }
+ return exe->flags;
+}
+
+EAPI void
+ecore_exe_pause(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause");
+ return;
+ }
+
+ if (exe->is_suspended)
+ return;
+
+ if (SuspendThread(exe->process_thread) != (DWORD)-1)
+ exe->is_suspended = 1;
+}
+
+EAPI void
+ecore_exe_continue(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_continue");
+ return;
+ }
+
+ if (!exe->is_suspended)
+ return;
+
+ if (ResumeThread(exe->process_thread) != (DWORD)-1)
+ exe->is_suspended = 0;
+}
+
+EAPI void
+ecore_exe_interrupt(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_interrupt");
+ return;
+ }
+
+ CloseHandle(exe->process_thread);
+ CloseHandle(exe->process);
+ exe->sig = ECORE_EXE_WIN32_SIGINT;
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+}
+
+EAPI void
+ecore_exe_quit(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_quit");
+ return;
+ }
+
+ CloseHandle(exe->process_thread);
+ CloseHandle(exe->process);
+ exe->sig = ECORE_EXE_WIN32_SIGQUIT;
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+}
+
+EAPI void
+ecore_exe_terminate(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_terminate");
+ return;
+ }
+
+/* CloseHandle(exe->thread); */
+ CloseHandle(exe->process);
+ exe->sig = ECORE_EXE_WIN32_SIGTERM;
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+}
+
+EAPI void
+ecore_exe_kill(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill");
+ return;
+ }
+
+ CloseHandle(exe->process_thread);
+ CloseHandle(exe->process);
+ exe->sig = ECORE_EXE_WIN32_SIGKILL;
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+}
+
+EAPI void
+ecore_exe_signal(Ecore_Exe *exe, int num __UNUSED__)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal");
+ return;
+ }
+
+ /* does nothing */
+}
+
+EAPI void
+ecore_exe_hup(Ecore_Exe *exe)
+{
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup");
+ return;
+ }
+
+ /* does nothing */
+}
+
+/* FIXME: manage error mode */
+static int
+_ecore_exe_win32_pipe_thread_generic_cb(void *data, Ecore_Exe_Flags flags)
+{
+#define BUFSIZE 2
+ char buf[BUFSIZE];
+ Ecore_Exe *exe;
+ char *current_buf = NULL;
+ HANDLE child_pipe;
+ Ecore_Pipe *ecore_pipe;
+ Ecore_Exe_Event_Data *event;
+ DWORD size;
+ DWORD current_size = 0;
+ BOOL res;
+
+ exe = (Ecore_Exe *)data;
+
+ /* Sort out what sort of handler we are. */
+ /* And get any left over data from last time. */
+ if ((exe->flags & ECORE_EXE_PIPE_READ) && (flags == ECORE_EXE_PIPE_READ))
+ {
+ child_pipe = exe->pipe_read.child_pipe;
+ ecore_pipe = exe->pipe_read.p;
+ flags = ECORE_EXE_PIPE_READ;
+ }
+ else if ((exe->flags & ECORE_EXE_PIPE_ERROR) && (flags == ECORE_EXE_PIPE_ERROR))
+ {
+ child_pipe = exe->pipe_error.child_pipe;
+ ecore_pipe = exe->pipe_error.p;
+ flags = ECORE_EXE_PIPE_ERROR;
+ }
+ else
+ return 0;
+
+ while (1)
+ {
+ if (!PeekNamedPipe(child_pipe, buf, 1, &size, ¤t_size, NULL))
+ continue;
+ if (size == 0)
+ continue;
+ current_buf = (char *)malloc(current_size);
+ if (!current_buf)
+ continue;
+ res = ReadFile(child_pipe, current_buf, current_size, &size, NULL);
+ if (!res || (size == 0))
+ {
+ free(current_buf);
+ current_buf = NULL;
+ continue;
+ }
+ if (current_size != size)
+ {
+ free(current_buf);
+ current_buf = NULL;
+ continue;
+ }
+ current_size = size;
+
+ if (flags == ECORE_EXE_PIPE_READ)
+ {
+ exe->pipe_read.data_buf = current_buf;
+ exe->pipe_read.data_size = current_size;
+ }
+ else
+ {
+ exe->pipe_error.data_buf = current_buf;
+ exe->pipe_error.data_size = current_size;
+ }
+
+ event = ecore_exe_event_data_get(exe, flags);
+ if (event)
+ ecore_pipe_write(ecore_pipe, &event, sizeof(event));
+
+ current_buf = NULL;
+ current_size = 0;
+ }
+
+ return 1;
+}
+
+static DWORD WINAPI
+_ecore_exe_win32_pipe_thread_read_cb(void *data)
+{
+ return _ecore_exe_win32_pipe_thread_generic_cb(data, ECORE_EXE_PIPE_READ);
+}
+
+static DWORD WINAPI
+_ecore_exe_win32_pipe_thread_error_cb(void *data)
+{
+ return _ecore_exe_win32_pipe_thread_generic_cb(data, ECORE_EXE_PIPE_ERROR);
+}
+
+static int
+_ecore_exe_win32_pipes_set(Ecore_Exe *exe)
+{
+ SECURITY_ATTRIBUTES sa;
+ HANDLE child_pipe;
+ HANDLE child_pipe_x;
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = EINA_TRUE;
+ sa.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&child_pipe, &child_pipe_x, &sa, 0))
+ return 0;
+ if (exe->flags & ECORE_EXE_PIPE_WRITE)
+ {
+ if (!SetHandleInformation(child_pipe_x, HANDLE_FLAG_INHERIT, 0))
+ goto close_pipe;
+ }
+ else
+ {
+ if (!SetHandleInformation(child_pipe, HANDLE_FLAG_INHERIT, 0))
+ goto close_pipe;
+ }
+
+ if (exe->flags & ECORE_EXE_PIPE_READ)
+ {
+ exe->pipe_read.child_pipe = child_pipe;
+ exe->pipe_read.child_pipe_x = child_pipe_x;
+ exe->pipe_read.p = ecore_pipe_add(_ecore_exe_pipe_read_cb, exe);
+ exe->pipe_read.thread = CreateThread(NULL, 0,
+ _ecore_exe_win32_pipe_thread_read_cb,
+ exe, 0, NULL);
+ }
+ else if (exe->flags & ECORE_EXE_PIPE_WRITE)
+ {
+ exe->pipe_write.child_pipe = child_pipe;
+ exe->pipe_write.child_pipe_x = child_pipe_x;
+/* exe->pipe_write.thread = CreateThread(NULL, 0, */
+/* _ecore_exe_win32_pipe_thread_cb, */
+/* exe, 0, NULL); */
+ }
+ else
+ {
+ exe->pipe_error.child_pipe = child_pipe;
+ exe->pipe_error.child_pipe_x = child_pipe_x;
+ exe->pipe_error.p = ecore_pipe_add(_ecore_exe_pipe_error_cb, exe);
+ exe->pipe_error.thread = CreateThread(NULL, 0,
+ _ecore_exe_win32_pipe_thread_error_cb,
+ exe, 0, NULL);
+ }
+
+ return 1;
+
+ close_pipe:
+ CloseHandle(child_pipe);
+ CloseHandle(child_pipe_x);
+
+ return 0;
+}
+
+static void
+_ecore_exe_win32_pipes_close(Ecore_Exe *exe)
+{
+ if (exe->flags & ECORE_EXE_PIPE_READ)
+ {
+ if (exe->pipe_read.child_pipe)
+ {
+ CloseHandle(exe->pipe_read.child_pipe);
+ exe->pipe_read.child_pipe = NULL;
+ }
+ if (exe->pipe_read.child_pipe_x)
+ {
+ CloseHandle(exe->pipe_read.child_pipe_x);
+ exe->pipe_read.child_pipe_x = NULL;
+ }
+ }
+
+ if (exe->flags & ECORE_EXE_PIPE_WRITE)
+ {
+ if (exe->pipe_write.child_pipe)
+ {
+ CloseHandle(exe->pipe_write.child_pipe);
+ exe->pipe_write.child_pipe = NULL;
+ }
+ if (exe->pipe_write.child_pipe_x)
+ {
+ CloseHandle(exe->pipe_write.child_pipe_x);
+ exe->pipe_write.child_pipe_x = NULL;
+ }
+ }
+
+ if (exe->flags & ECORE_EXE_PIPE_ERROR)
+ {
+ if (exe->pipe_error.child_pipe)
+ {
+ CloseHandle(exe->pipe_error.child_pipe);
+ exe->pipe_error.child_pipe = NULL;
+ }
+ if (exe->pipe_error.child_pipe_x)
+ {
+ CloseHandle(exe->pipe_error.child_pipe_x);
+ exe->pipe_error.child_pipe_x = NULL;
+ }
+ }
+}
+
+static DWORD WINAPI
+_ecore_exe_thread_procedure(LPVOID data __UNUSED__)
+{
+ GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
+ return 1;
+}
+
+static BOOL CALLBACK
+_ecore_exe_enum_windows_procedure(HWND window, LPARAM data)
+{
+ Ecore_Exe *exe;
+ DWORD thread_id;
+
+ exe = (Ecore_Exe *)data;
+ thread_id = GetWindowThreadProcessId(window, NULL);
+
+ if (thread_id == exe->thread_id)
+ {
+ /* Ctrl-C or Ctrl-Break */
+ if (CreateRemoteThread(exe->process, NULL, 0,
+ (LPTHREAD_START_ROUTINE)_ecore_exe_thread_procedure, NULL,
+ 0, NULL))
+ {
+ printf ("remote thread\n");
+ return EINA_FALSE;
+ }
+
+ if ((exe->sig == ECORE_EXE_WIN32_SIGINT) ||
+ (exe->sig == ECORE_EXE_WIN32_SIGQUIT))
+ {
+ printf ("int or quit\n");
+ return EINA_FALSE;
+ }
+
+ /* WM_CLOSE message */
+ PostMessage(window, WM_CLOSE, 0, 0);
+ if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ printf ("CLOSE\n");
+ return EINA_FALSE;
+ }
+
+ /* WM_QUIT message */
+ PostMessage(window, WM_QUIT, 0, 0);
+ if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ printf ("QUIT\n");
+ return EINA_FALSE;
+ }
+
+ /* Exit process */
+ if (CreateRemoteThread(exe->process, NULL, 0,
+ (LPTHREAD_START_ROUTINE)ExitProcess, NULL,
+ 0, NULL))
+ {
+ printf ("remote thread 2\n");
+ return EINA_FALSE;
+ }
+
+ if (exe->sig == ECORE_EXE_WIN32_SIGTERM)
+ {
+ printf ("term\n");
+ return EINA_FALSE;
+ }
+
+ TerminateProcess(exe->process, 0);
+
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_ecore_exe_event_add_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Exe_Event_Add *e;
+
+ e = (Ecore_Exe_Event_Add *)ev;
+ free(e);
+}
+
+static void
+_ecore_exe_event_del_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Exe_Event_Del *e;
+
+ e = (Ecore_Exe_Event_Del *)ev;
+ if (e->exe)
+ ecore_exe_free(e->exe);
+ free(e);
+}
+
+static void
+_ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Exe_Event_Data *e;
+
+ e = (Ecore_Exe_Event_Data *)ev;
+ ecore_exe_event_data_free(e);
+}
+
+static int
+_ecore_exe_close_cb(void *data, Ecore_Win32_Handler *wh __UNUSED__)
+{
+ Ecore_Exe_Event_Del *e;
+ Ecore_Exe *exe;
+ DWORD exit_code = 0;
+
+ e = calloc(1, sizeof(Ecore_Exe_Event_Del));
+ if (!e) return 0;
+
+ exe = (Ecore_Exe *)data;
+
+ if (GetExitCodeProcess(exe->process2, &exit_code))
+ {
+ e->exit_code = exit_code;
+ e->exited = 1;
+ }
+ else
+ {
+ char *msg;
+
+ msg = evil_last_error_get();
+ printf("%s\n", msg);
+ free(msg);
+ }
+ e->pid = exe->process_id;
+ e->exe = exe;
+
+ ecore_event_add(ECORE_EXE_EVENT_DEL, e,
+ _ecore_exe_event_del_free, NULL);
+
+ return 0;
+}
+
+static void
+_ecore_exe_pipe_read_cb(void *data, void *buf, unsigned int size)
+{
+ Ecore_Exe_Event_Data *e;
+
+ e = *((Ecore_Exe_Event_Data **)buf);
+ if (e)
+ ecore_event_add(ECORE_EXE_EVENT_DATA, e,
+ _ecore_exe_event_exe_data_free,
+ NULL);
+}
+
+static int
+_ecore_exe_pipe_write_cb(void *data, Ecore_Win32_Handler *wh __UNUSED__)
+{
+ char buf[READBUFSIZ];
+ Ecore_Exe *exe;
+ DWORD num_exe;
+ BOOL res;
+
+ exe = (Ecore_Exe *)data;
+
+ res = WriteFile(exe->pipe_write.child_pipe_x, buf, READBUFSIZ, &num_exe, NULL);
+ if (!res || num_exe == 0)
+ {
+ /* FIXME: what to do here ?? */
+ }
+
+ if (exe->close_stdin == 1)
+ {
+ if (exe->pipe_write.h)
+ {
+ ecore_main_win32_handler_del(exe->pipe_write.h);
+ exe->pipe_write.h = NULL;
+ }
+ exe->pipe_write.h = NULL;
+ CloseHandle(exe->pipe_write.child_pipe);
+ exe->pipe_write.child_pipe = NULL;
+ }
+
+ return 1;
+}
+
+static void
+_ecore_exe_pipe_error_cb(void *data, void *buf, unsigned int size)
+{
+ Ecore_Exe_Event_Data *e;
+
+ e = *((Ecore_Exe_Event_Data **)buf);
+ if (e)
+ ecore_event_add(ECORE_EXE_EVENT_ERROR, e,
+ _ecore_exe_event_exe_data_free,
+ NULL);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+void
+_ecore_exe_init(void)
+{
+}
+
+void
+_ecore_exe_shutdown(void)
+{
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif defined __GNUC__
+# define alloca __builtin_alloca
+#elif defined _AIX
+# define alloca __alloca
+#elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+#else
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+#else
+# define gettext(x) (x)
+# define dgettext(domain, x) (x)
+#endif
+
+#define _(x) dgettext("ecore", x)
+
+#ifdef _WIN32_WCE
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "Ecore_Getopt.h"
+
+static const char *prog = NULL;
+static char **argv = NULL;
+static int argc = 0;
+static int cols = 80;
+static int helpcol = 80 / 3;
+
+static void
+_ecore_getopt_help_print_replace_program(FILE *fp, const Ecore_Getopt *parser __UNUSED__, const char *text)
+{
+ do
+ {
+ const char *d = strchr(text, '%');
+
+ if (!d)
+ {
+ fputs(text, fp);
+ break;
+ }
+
+ if (fwrite(text, 1, d - text, fp) != (size_t)(d - text))
+ return;
+ d++;
+ if (strncmp(d, "prog", sizeof("prog") - 1) == 0)
+ {
+ fputs(prog ? prog : "???", fp);
+ d += sizeof("prog") - 1;
+ }
+ else
+ {
+ if (d[0] == '%')
+ d++;
+ fputc('%', fp);
+ }
+
+ text = d;
+ }
+ while (text[0] != '\0');
+
+ fputc('\n', fp);
+}
+
+static void
+_ecore_getopt_version(FILE *fp, const Ecore_Getopt *parser)
+{
+ fputs(_("Version:"), fp);
+ fputc(' ', fp);
+ _ecore_getopt_help_print_replace_program(fp, parser, parser->version);
+}
+
+static void
+_ecore_getopt_help_usage(FILE *fp, const Ecore_Getopt *parser)
+{
+ fputs(_("Usage:"), fp);
+ fputc(' ', fp);
+
+ if (!parser->usage)
+ {
+ fprintf(fp, _("%s [options]\n"), prog);
+ return;
+ }
+
+ _ecore_getopt_help_print_replace_program(fp, parser, gettext(parser->usage));
+}
+
+static int
+_ecore_getopt_help_line(FILE *fp, const int base, const int total, int used, const char *text, int len)
+{
+ int linebreak = 0;
+ do
+ {
+ /* process line considering spaces (new line and tabs are spaces!) */
+ while ((used < total) && (len > 0))
+ {
+ const char *space = NULL;
+ int i, todo;
+
+ todo = total - used;
+ if (todo > len)
+ todo = len;
+
+ for (i = 0; i < todo; i++)
+ if (isspace(text[i]))
+ {
+ space = text + i;
+ break;
+ }
+
+ if (space)
+ {
+ i = fwrite(text, 1, i, fp);
+ i++;
+ text += i;
+ len -= i;
+ used += i;
+
+ if (linebreak)
+ {
+ linebreak = 0;
+ continue;
+ }
+
+ if (space[0] == '\n')
+ break;
+ else if (space[0] == '\t')
+ {
+ int c;
+
+ used--;
+ c = ((used / 8) + 1) * 8;
+ if (c < total)
+ {
+ for (; used < c; used++)
+ fputc(' ', fp);
+ }
+ else
+ {
+ text--;
+ len++;
+ break;
+ }
+ }
+ else if (used < total)
+ fputc(space[0], fp);
+ }
+ else
+ {
+ i = fwrite(text, 1, i, fp);
+ text += i;
+ len -= i;
+ used += i;
+ }
+ linebreak = 0;
+ }
+ if (len <= 0)
+ break;
+ linebreak = 1;
+ fputc('\n', fp);
+ for (used = 0; used < base; used++)
+ fputc(' ', fp);
+ }
+ while (1);
+
+ return used;
+}
+
+static void
+_ecore_getopt_help_description(FILE *fp, const Ecore_Getopt *parser)
+{
+ const char *p, *prg, *ver;
+ int used, prglen, verlen;
+
+ p = gettext(parser->description);
+ if (!p)
+ return;
+
+ fputc('\n', fp);
+
+ prg = prog ? prog : "???";
+ ver = parser->version ? parser->version : "???";
+
+ prglen = strlen(prg);
+ verlen = strlen(ver);
+
+ used = 0;
+
+ do
+ {
+ const char *d = strchr(p, '%');
+
+ if (!d)
+ {
+ _ecore_getopt_help_line(fp, 0, cols, used, p, strlen(p));
+ break;
+ }
+
+ used = _ecore_getopt_help_line(fp, 0, cols, used, p, d - p);
+ d++;
+ if (strncmp(d, "prog", sizeof("prog") - 1) == 0)
+ {
+ used = _ecore_getopt_help_line(fp, 0, cols, used, prg, prglen);
+ d += sizeof("prog") - 1;
+ }
+ else if (strncmp(d, "version", sizeof("version") - 1) == 0)
+ {
+ used = _ecore_getopt_help_line(fp, 0, cols, used, ver, verlen);
+ d += sizeof("version") - 1;
+ }
+ else
+ {
+ if (d[0] == '%')
+ d++;
+ used = _ecore_getopt_help_line(fp, 0, cols, used, "%", 1);
+ }
+
+ p = d;
+ }
+ while (p[0] != '\0');
+
+ fputs("\n\n", fp);
+}
+
+static void
+_ecore_getopt_copyright(FILE *fp, const Ecore_Getopt *parser)
+{
+ const char *txt = gettext(parser->copyright);
+ fputs(_("Copyright:"), fp);
+ fputs("\n ", fp);
+ _ecore_getopt_help_line
+ (fp, 3, cols, 3, txt, strlen(txt));
+ fputc('\n', fp);
+}
+
+static void
+_ecore_getopt_license(FILE *fp, const Ecore_Getopt *parser)
+{
+ const char *txt = gettext(parser->license);
+ fputs(_("License:"), fp);
+ fputs("\n ", fp);
+ _ecore_getopt_help_line
+ (fp, 3, cols, 3, txt, strlen(txt));
+ fputc('\n', fp);
+}
+
+static Ecore_Getopt_Desc_Arg_Requirement
+_ecore_getopt_desc_arg_requirement(const Ecore_Getopt_Desc *desc)
+{
+ switch (desc->action)
+ {
+ case ECORE_GETOPT_ACTION_STORE:
+ return desc->action_param.store.arg_req;
+ case ECORE_GETOPT_ACTION_STORE_CONST:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ case ECORE_GETOPT_ACTION_STORE_TRUE:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ case ECORE_GETOPT_ACTION_STORE_FALSE:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ case ECORE_GETOPT_ACTION_CHOICE:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
+ case ECORE_GETOPT_ACTION_APPEND:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
+ case ECORE_GETOPT_ACTION_COUNT:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ case ECORE_GETOPT_ACTION_CALLBACK:
+ return desc->action_param.callback.arg_req;
+ case ECORE_GETOPT_ACTION_HELP:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ case ECORE_GETOPT_ACTION_VERSION:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ default:
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ }
+}
+
+static void
+_ecore_getopt_help_desc_setup_metavar(const Ecore_Getopt_Desc *desc, char *metavar, int *metavarlen, int maxsize)
+{
+ if (desc->metavar)
+ {
+ const char *txt = gettext(desc->metavar);
+ *metavarlen = strlen(txt);
+ if (*metavarlen > maxsize - 1)
+ *metavarlen = maxsize - 1;
+
+ memcpy(metavar, txt, *metavarlen);
+ metavar[*metavarlen] = '\0';
+ }
+ else if (desc->longname)
+ {
+ int i;
+
+ *metavarlen = strlen(desc->longname);
+ if (*metavarlen > maxsize - 1)
+ *metavarlen = maxsize - 1;
+
+ for (i = 0; i < *metavarlen; i++)
+ metavar[i] = toupper(desc->longname[i]);
+ metavar[i] = '\0';
+ }
+}
+
+static int
+_ecore_getopt_help_desc_show_arg(FILE *fp, Ecore_Getopt_Desc_Arg_Requirement requirement, const char *metavar, int metavarlen)
+{
+ int used;
+
+ if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
+ return 0;
+
+ used = 0;
+
+ if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL)
+ {
+ fputc('[', fp);
+ used++;
+ }
+
+ if (requirement != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
+ {
+ fputc('=', fp);
+ fputs(metavar, fp);
+ used += metavarlen + 1;
+ }
+
+ if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL)
+ {
+ fputc(']', fp);
+ used++;
+ }
+
+ return used;
+}
+
+static int
+_ecore_getopt_help_desc_store(FILE *fp, const int base, const int total, int used, const Ecore_Getopt_Desc *desc)
+{
+ const Ecore_Getopt_Desc_Store *store = &desc->action_param.store;
+ char buf[64];
+ const char *str;
+ size_t len;
+
+ fputc('\n', fp);
+ for (used = 0; used < base; used++)
+ fputc(' ', fp);
+
+ switch (store->type)
+ {
+ case ECORE_GETOPT_TYPE_STR:
+ str = "STR";
+ len = sizeof("STR") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_BOOL:
+ str = "BOOL";
+ len = sizeof("BOOL") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_SHORT:
+ str = "SHORT";
+ len = sizeof("SHORT") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_INT:
+ str = "INT";
+ len = sizeof("INT") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_LONG:
+ str = "LONG";
+ len = sizeof("LONG") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_USHORT:
+ str = "USHORT";
+ len = sizeof("USHORT") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_UINT:
+ str = "UINT";
+ len = sizeof("UINT") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_ULONG:
+ str = "ULONG";
+ len = sizeof("ULONG") - 1;
+ break;
+ case ECORE_GETOPT_TYPE_DOUBLE:
+ str = "DOUBLE";
+ len = sizeof("DOUBLE") - 1;
+ break;
+ default:
+ str = "???";
+ len = sizeof("???") - 1;
+ }
+
+ used = _ecore_getopt_help_line
+ (fp, base, total, used, _("Type: "), strlen(_("Type: ")));
+ used = _ecore_getopt_help_line(fp, base, total, used, str, len);
+
+ if (store->arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES)
+ goto end;
+
+ used = _ecore_getopt_help_line
+ (fp, base, total, used, ". ", sizeof(". ") - 1);
+
+ switch (store->type)
+ {
+ case ECORE_GETOPT_TYPE_STR:
+ str = store->def.strv;
+ len = str ? strlen(str) : 0;
+ break;
+ case ECORE_GETOPT_TYPE_BOOL:
+ str = store->def.boolv ? "true" : "false";
+ len = strlen(str);
+ break;
+ case ECORE_GETOPT_TYPE_SHORT:
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%hd", store->def.shortv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+ case ECORE_GETOPT_TYPE_INT:
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%d", store->def.intv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+ case ECORE_GETOPT_TYPE_LONG:
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%ld", store->def.longv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+ case ECORE_GETOPT_TYPE_USHORT:
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%hu", store->def.ushortv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+ case ECORE_GETOPT_TYPE_UINT:
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%u", store->def.uintv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+ case ECORE_GETOPT_TYPE_ULONG:
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%lu", store->def.ulongv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+ case ECORE_GETOPT_TYPE_DOUBLE:
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%f", store->def.doublev);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+ default:
+ str = "???";
+ len = sizeof("???") - 1;
+ }
+
+ used = _ecore_getopt_help_line
+ (fp, base, total, used, _("Default: "), strlen(_("Default: ")));
+ used = _ecore_getopt_help_line(fp, base, total, used, str, len);
+
+ end:
+ return _ecore_getopt_help_line(fp, base, total, used, ".", 1);
+}
+
+static int
+_ecore_getopt_help_desc_choices(FILE *fp, const int base, const int total, int used, const Ecore_Getopt_Desc *desc)
+{
+ const char *const *itr;
+ const char sep[] = ", ";
+ const int seplen = sizeof(sep) - 1;
+
+ if (used > 0)
+ {
+ fputc('\n', fp);
+ used = 0;
+ }
+ for (; used < base; used++)
+ fputc(' ', fp);
+
+ used = _ecore_getopt_help_line
+ (fp, base, total, used, _("Choices: "), strlen(_("Choices: ")));
+
+ for (itr = desc->action_param.choices; *itr != NULL; itr++)
+ {
+ used = _ecore_getopt_help_line
+ (fp, base, total, used, *itr, strlen(*itr));
+ if (itr[1] != NULL)
+ used = _ecore_getopt_help_line(fp, base, total, used, sep, seplen);
+ }
+
+ return _ecore_getopt_help_line(fp, base, total, used, ".", 1);
+}
+
+static void
+_ecore_getopt_help_desc(FILE *fp, const Ecore_Getopt_Desc *desc)
+{
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ char metavar[32] = "ARG";
+ int metavarlen = 3;
+ int used;
+
+ arg_req = _ecore_getopt_desc_arg_requirement(desc);
+ if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
+ _ecore_getopt_help_desc_setup_metavar
+ (desc, metavar, &metavarlen, sizeof(metavar));
+
+ fputs(" ", fp);
+ used = 2;
+
+ if (desc->shortname)
+ {
+ fputc('-', fp);
+ fputc(desc->shortname, fp);
+ used += 2;
+ used += _ecore_getopt_help_desc_show_arg
+ (fp, arg_req, metavar, metavarlen);
+ }
+
+ if (desc->shortname && desc->longname)
+ {
+ fputs(", ", fp);
+ used += 2;
+ }
+
+ if (desc->longname)
+ {
+ int namelen = strlen(desc->longname);
+
+ fputs("--", fp);
+ fputs(desc->longname, fp);
+ used += 2 + namelen;
+ used += _ecore_getopt_help_desc_show_arg
+ (fp, arg_req, metavar, metavarlen);
+ }
+
+ if (!desc->help)
+ goto end;
+
+ if (used + 3 >= helpcol)
+ {
+ fputc('\n', fp);
+ used = 0;
+ }
+
+ for (; used < helpcol; used++)
+ fputc(' ', fp);
+
+ used = _ecore_getopt_help_line
+ (fp, helpcol, cols, used, desc->help, strlen(desc->help));
+
+ switch (desc->action)
+ {
+ case ECORE_GETOPT_ACTION_STORE:
+ _ecore_getopt_help_desc_store(fp, helpcol, cols, used, desc);
+ break;
+ case ECORE_GETOPT_ACTION_CHOICE:
+ _ecore_getopt_help_desc_choices(fp, helpcol, cols, used, desc);
+ break;
+ default:
+ break;
+ }
+
+ end:
+ fputc('\n', fp);
+}
+
+static unsigned char
+_ecore_getopt_desc_is_sentinel(const Ecore_Getopt_Desc *desc)
+{
+ return (desc->shortname == '\0') && (desc->longname == NULL);
+}
+
+static void
+_ecore_getopt_help_options(FILE *fp, const Ecore_Getopt *parser)
+{
+ const Ecore_Getopt_Desc *desc;
+
+ fputs(_("Options:\n"), fp);
+
+ for (desc = parser->descs; !_ecore_getopt_desc_is_sentinel(desc); desc++)
+ _ecore_getopt_help_desc(fp, desc);
+
+ fputc('\n', fp);
+}
+
+/**
+ * Show nicely formatted help message for the given parser.
+ *
+ * Message will be print to stderr.
+ */
+void
+ecore_getopt_help(FILE *fp, const Ecore_Getopt *parser)
+{
+ const char *var;
+
+ if (!parser) return;
+
+ if (argc < 1)
+ {
+ ecore_app_args_get(&argc, &argv);
+ if ((argc > 0) && (argv[0] != NULL))
+ prog = argv[0];
+ else
+ prog = parser->prog;
+ }
+
+ var = getenv("COLUMNS");
+ if (var)
+ {
+ cols = atoi(var);
+ if (cols < 20)
+ cols = 20;
+
+ helpcol = cols / 3;
+ }
+
+ _ecore_getopt_help_usage(fp, parser);
+ _ecore_getopt_help_description(fp, parser);
+ _ecore_getopt_help_options(fp, parser);
+}
+
+static const Ecore_Getopt_Desc *
+_ecore_getopt_parse_find_long(const Ecore_Getopt *parser, const char *name)
+{
+ const Ecore_Getopt_Desc *desc = parser->descs;
+ const char *p = strchr(name, '=');
+ int len = 0;
+
+ if (p)
+ len = p - name;
+
+ for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
+ {
+ if (!desc->longname)
+ continue;
+
+ if (p)
+ {
+ if ((strncmp(name, desc->longname, len) == 0) &&
+ (desc->longname[len] == '\0'))
+ return desc;
+ }
+ else
+ {
+ if (strcmp(name, desc->longname) == 0)
+ return desc;
+ }
+ }
+
+ return NULL;
+}
+
+static const Ecore_Getopt_Desc *
+_ecore_getopt_parse_find_short(const Ecore_Getopt *parser, char name)
+{
+ const Ecore_Getopt_Desc *desc = parser->descs;
+ for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
+ if (name == desc->shortname)
+ return desc;
+ return NULL;
+}
+
+static int
+_ecore_getopt_parse_find_nonargs_base(const Ecore_Getopt *parser, int argc, char **argv)
+{
+ char **nonargs;
+ int src, dst, used, base;
+
+ nonargs = alloca(sizeof(char*) * argc);
+ src = 1;
+ dst = 1;
+ used = 0;
+ base = 0;
+ while (src < argc)
+ {
+ const Ecore_Getopt_Desc *desc;
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ char *arg = argv[src];
+
+ if (arg[0] != '-')
+ goto found_nonarg;
+
+ if (arg[1] == '-')
+ {
+ if (arg[2] == '\0') /* explicit end of options, "--" */
+ {
+ base = 1;
+ break;
+ }
+ desc = _ecore_getopt_parse_find_long(parser, arg + 2);
+ }
+ else
+ desc = _ecore_getopt_parse_find_short(parser, arg[1]);
+
+ if (!desc)
+ {
+ if (arg[1] == '-')
+ fprintf(stderr, _("ERROR: unknown option --%s.\n"), arg + 2);
+ else
+ fprintf(stderr, _("ERROR: unknown option -%c.\n"), arg[1]);
+ if (parser->strict)
+ {
+ memmove(argv + dst, nonargs, used * sizeof(char *));
+ return -1;
+ }
+ else
+ goto found_nonarg;
+ }
+
+ if (src != dst)
+ argv[dst] = argv[src];
+ src++;
+ dst++;
+
+ arg_req = _ecore_getopt_desc_arg_requirement(desc);
+ if (arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
+ continue;
+
+ if (strchr(arg, '='))
+ continue;
+
+ if ((src >= argc) || (argv[src][0] == '-'))
+ continue;
+
+ if (src != dst)
+ argv[dst] = argv[src];
+ src++;
+ dst++;
+ continue;
+
+ found_nonarg:
+ nonargs[used] = arg;
+ used++;
+ src++;
+ }
+
+ if (!base) /* '--' not found */
+ base = dst;
+ else
+ {
+ base = dst;
+ if (src != dst)
+ argv[dst] = argv[src];
+ dst++;
+ }
+
+ memmove(argv + dst, nonargs, used * sizeof(char *));
+ return base;
+}
+
+static void
+_ecore_getopt_desc_print_error(const Ecore_Getopt_Desc *desc, const char *fmt, ...)
+{
+ va_list ap;
+
+ fputs(_("ERROR: "), stderr);
+
+ if (desc->shortname)
+ {
+ fputc('-', stderr);
+ fputc(desc->shortname, stderr);
+ }
+
+ if (desc->shortname && desc->longname)
+ fputs(", ", stderr);
+
+ if (desc->longname)
+ {
+ fputs("--", stderr);
+ fputs(desc->longname, stderr);
+ }
+
+ fputs(": ", stderr);
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+static unsigned char
+_ecore_getopt_parse_bool(const char *str, unsigned char *v)
+{
+ if ((strcmp(str, "0") == 0) ||
+ (strcasecmp(str, "f") == 0) ||
+ (strcasecmp(str, "false") == 0) ||
+ (strcasecmp(str, "no") == 0) ||
+ (strcasecmp(str, "off") == 0)
+ )
+ {
+ *v = 0;
+ return 1;
+ }
+ else if ((strcmp(str, "1") == 0) ||
+ (strcasecmp(str, "t") == 0) ||
+ (strcasecmp(str, "true") == 0) ||
+ (strcasecmp(str, "yes") == 0) ||
+ (strcasecmp(str, "on") == 0)
+ )
+ {
+ *v = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+static unsigned char
+_ecore_getopt_parse_long(const char *str, long int *v)
+{
+ char *endptr = NULL;
+ *v = strtol(str, &endptr, 0);
+ return endptr > str;
+}
+
+static unsigned char
+_ecore_getopt_parse_double(const char *str, double *v)
+{
+ char *endptr = NULL;
+ *v = strtod(str, &endptr);
+ return endptr > str;
+}
+
+static unsigned char
+_ecore_getopt_parse_store(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *value, const char *arg_val)
+{
+ const Ecore_Getopt_Desc_Store *store = &desc->action_param.store;
+ long int v;
+ double d;
+ unsigned char b;
+
+ if (!value->ptrp)
+ {
+ _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+
+ switch (store->arg_req)
+ {
+ case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO:
+ goto use_optional;
+ case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL:
+ if (!arg_val)
+ goto use_optional;
+ case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES:
+ break;
+ }
+
+ switch (store->type)
+ {
+ case ECORE_GETOPT_TYPE_STR:
+ *value->strp = (char *)arg_val;
+ return 1;
+ case ECORE_GETOPT_TYPE_BOOL:
+ if (_ecore_getopt_parse_bool(arg_val, &b))
+ {
+ *value->boolp = b;
+ return 1;
+ }
+ else
+ {
+ _ecore_getopt_desc_print_error
+ (desc, _("unknown boolean value %s.\n"), arg_val);
+ return 0;
+ }
+ case ECORE_GETOPT_TYPE_SHORT:
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->shortp = v;
+ return 1;
+ case ECORE_GETOPT_TYPE_INT:
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->intp = v;
+ return 1;
+ case ECORE_GETOPT_TYPE_LONG:
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->longp = v;
+ return 1;
+ case ECORE_GETOPT_TYPE_USHORT:
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->ushortp = v;
+ return 1;
+ case ECORE_GETOPT_TYPE_UINT:
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->uintp = v;
+ return 1;
+ case ECORE_GETOPT_TYPE_ULONG:
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->ulongp = v;
+ return 1;
+ case ECORE_GETOPT_TYPE_DOUBLE:
+ if (!_ecore_getopt_parse_double(arg_val, &d))
+ goto error;
+ *value->doublep = d;
+ break;
+ }
+
+ return 1;
+
+ error:
+ _ecore_getopt_desc_print_error
+ (desc, _("invalid number format %s\n"), arg_val);
+ return 0;
+
+ use_optional:
+ switch (store->type)
+ {
+ case ECORE_GETOPT_TYPE_STR:
+ *value->strp = (char *)store->def.strv;
+ break;
+ case ECORE_GETOPT_TYPE_BOOL:
+ *value->boolp = store->def.boolv;
+ break;
+ case ECORE_GETOPT_TYPE_SHORT:
+ *value->shortp = store->def.shortv;
+ break;
+ case ECORE_GETOPT_TYPE_INT:
+ *value->intp = store->def.intv;
+ break;
+ case ECORE_GETOPT_TYPE_LONG:
+ *value->longp = store->def.longv;
+ break;
+ case ECORE_GETOPT_TYPE_USHORT:
+ *value->ushortp = store->def.ushortv;
+ break;
+ case ECORE_GETOPT_TYPE_UINT:
+ *value->uintp = store->def.uintv;
+ break;
+ case ECORE_GETOPT_TYPE_ULONG:
+ *value->ulongp = store->def.ulongv;
+ break;
+ case ECORE_GETOPT_TYPE_DOUBLE:
+ *value->doublep = store->def.doublev;
+ break;
+ }
+
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_store_const(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (!val->ptrp)
+ {
+ _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+
+ *val->ptrp = (void *)desc->action_param.store_const;
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_store_true(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (!val->boolp)
+ {
+ _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+ *val->boolp = 1;
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_store_false(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (!val->boolp)
+ {
+ _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+ *val->boolp = 0;
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_choice(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val)
+{
+ const char * const *pchoice;
+
+ if (!val->strp)
+ {
+ _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+
+ pchoice = desc->action_param.choices;
+ for (; *pchoice != NULL; pchoice++)
+ if (strcmp(*pchoice, arg_val) == 0)
+ {
+ *val->strp = (char *)*pchoice;
+ return 1;
+ }
+
+ _ecore_getopt_desc_print_error
+ (desc, _("invalid choice \"%s\". Valid values are: "), arg_val);
+
+ pchoice = desc->action_param.choices;
+ for (; *pchoice != NULL; pchoice++)
+ {
+ fputs(*pchoice, stderr);
+ if (pchoice[1] != NULL)
+ fputs(", ", stderr);
+ }
+
+ fputs(".\n", stderr);
+ return 0;
+}
+
+static unsigned char
+_ecore_getopt_parse_append(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val)
+{
+ void *data;
+ long int v;
+ double d;
+ unsigned char b;
+
+ if (!arg_val)
+ {
+ _ecore_getopt_desc_print_error
+ (desc, _("missing parameter to append.\n"));
+ return 0;
+ }
+
+ if (!val->listp)
+ {
+ _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+
+ switch (desc->action_param.append_type)
+ {
+ case ECORE_GETOPT_TYPE_STR:
+ data = strdup(arg_val);
+ break;
+ case ECORE_GETOPT_TYPE_BOOL:
+ {
+ if (_ecore_getopt_parse_bool(arg_val, &b))
+ {
+ data = malloc(sizeof(unsigned char));
+ if (data)
+ *(unsigned char *)data = b;
+ }
+ else
+ {
+ _ecore_getopt_desc_print_error
+ (desc, _("unknown boolean value %s.\n"), arg_val);
+ return 0;
+ }
+ }
+ break;
+ case ECORE_GETOPT_TYPE_SHORT:
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(short));
+ if (data)
+ *(short *)data = (short)v;
+ }
+ break;
+ case ECORE_GETOPT_TYPE_INT:
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(int));
+ if (data)
+ *(int *)data = (int)v;
+ }
+ break;
+ case ECORE_GETOPT_TYPE_LONG:
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(long));
+ if (data)
+ *(long *)data = v;
+ }
+ break;
+ case ECORE_GETOPT_TYPE_USHORT:
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(unsigned short));
+ if (data)
+ *(unsigned short *)data = (unsigned short)v;
+ }
+ break;
+ case ECORE_GETOPT_TYPE_UINT:
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(unsigned int));
+ if (data)
+ *(unsigned int *)data = (unsigned int)v;
+ }
+ break;
+ case ECORE_GETOPT_TYPE_ULONG:
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(unsigned long));
+ if (data)
+ *(unsigned long *)data = v;
+ }
+ break;
+ case ECORE_GETOPT_TYPE_DOUBLE:
+ {
+ if (!_ecore_getopt_parse_double(arg_val, &d))
+ goto error;
+ data = malloc(sizeof(double));
+ if (data)
+ *(double *)data = d;
+ }
+ break;
+ default:
+ {
+ _ecore_getopt_desc_print_error(desc, _("could not parse value.\n"));
+ return 0;
+ }
+ }
+
+ *val->listp = eina_list_append(*val->listp, data);
+ return 1;
+
+ error:
+ _ecore_getopt_desc_print_error
+ (desc, _("invalid number format %s\n"), arg_val);
+ return 0;
+}
+
+static unsigned char
+_ecore_getopt_parse_count(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (!val->intp)
+ {
+ _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+
+ (*val->intp)++;
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_callback(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val)
+{
+ const Ecore_Getopt_Desc_Callback *cb = &desc->action_param.callback;
+
+ switch (cb->arg_req)
+ {
+ case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO:
+ arg_val = cb->def;
+ break;
+ case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL:
+ if (!arg_val)
+ arg_val = cb->def;
+ break;
+ case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES:
+ break;
+ }
+
+ if (cb->arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
+ {
+ if ((!arg_val) || (arg_val[0] == '\0'))
+ {
+ _ecore_getopt_desc_print_error(desc, _("missing parameter.\n"));
+ return 0;
+ }
+
+ if (!val->ptrp)
+ {
+ _ecore_getopt_desc_print_error
+ (desc, _("value has no pointer set.\n"));
+ return 0;
+ }
+ }
+
+ if (!cb->func)
+ {
+ _ecore_getopt_desc_print_error(desc, _("missing callback function!\n"));
+ return 0;
+ }
+
+ return cb->func(parser, desc, arg_val, (void *)cb->data, val);
+}
+
+static unsigned char
+_ecore_getopt_parse_help(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc __UNUSED__, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (val->boolp)
+ (*val->boolp) = 1;
+ ecore_getopt_help(stdout, parser);
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_version(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (val->boolp)
+ (*val->boolp) = 1;
+ if (!parser->version)
+ {
+ _ecore_getopt_desc_print_error(desc, _("no version was defined.\n"));
+ return 0;
+ }
+ _ecore_getopt_version(stdout, parser);
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_copyright(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (val->boolp)
+ (*val->boolp) = 1;
+ if (!parser->copyright)
+ {
+ _ecore_getopt_desc_print_error(desc, _("no copyright was defined.\n"));
+ return 0;
+ }
+ _ecore_getopt_copyright(stdout, parser);
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_license(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+{
+ if (val->boolp)
+ (*val->boolp) = 1;
+ if (!parser->license)
+ {
+ _ecore_getopt_desc_print_error(desc, _("no license was defined.\n"));
+ return 0;
+ }
+ _ecore_getopt_license(stdout, parser);
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_desc_handle(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *value, const char *arg_val)
+{
+ switch (desc->action)
+ {
+ case ECORE_GETOPT_ACTION_STORE:
+ return _ecore_getopt_parse_store(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_STORE_CONST:
+ return _ecore_getopt_parse_store_const(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_STORE_TRUE:
+ return _ecore_getopt_parse_store_true(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_STORE_FALSE:
+ return _ecore_getopt_parse_store_false(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_CHOICE:
+ return _ecore_getopt_parse_choice(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_APPEND:
+ return _ecore_getopt_parse_append(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_COUNT:
+ return _ecore_getopt_parse_count(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_CALLBACK:
+ return _ecore_getopt_parse_callback(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_HELP:
+ return _ecore_getopt_parse_help(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_VERSION:
+ return _ecore_getopt_parse_version(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_COPYRIGHT:
+ return _ecore_getopt_parse_copyright(parser, desc, value, arg_val);
+ case ECORE_GETOPT_ACTION_LICENSE:
+ return _ecore_getopt_parse_license(parser, desc, value, arg_val);
+ default:
+ return 0;
+ }
+}
+
+static unsigned char
+_ecore_getopt_parse_arg_long(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc __UNUSED__, char **argv, int *idx, int *nonargs, const char *arg)
+{
+ const Ecore_Getopt_Desc *desc;
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ const char *arg_val;
+ int desc_idx;
+ Ecore_Getopt_Value *value;
+ unsigned char ret;
+
+ desc = _ecore_getopt_parse_find_long(parser, arg);
+ if (!desc)
+ {
+ fprintf(stderr, _("ERROR: unknown option --%s, ignored.\n"), arg);
+ if (parser->strict)
+ return 0;
+
+ (*idx)++;
+ return 1;
+ }
+
+ (*idx)++;
+
+ arg_req = _ecore_getopt_desc_arg_requirement(desc);
+ if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
+ {
+ arg_val = strchr(arg, '=');
+ if (arg_val)
+ arg_val++;
+ else
+ {
+ if ((*idx < *nonargs) && (argv[*idx][0] != '-'))
+ {
+ arg_val = argv[*idx];
+ (*idx)++;
+ }
+ else
+ arg_val = NULL;
+ }
+
+ if (arg_val && arg_val[0] == '\0')
+ arg_val = NULL;
+
+ if ((!arg_val) && (arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES))
+ {
+ fprintf
+ (stderr, _("ERROR: option --%s requires an argument!\n"), arg);
+ if (parser->strict)
+ return 0;
+ return 1;
+ }
+ }
+ else
+ arg_val = NULL;
+
+ desc_idx = desc - parser->descs;
+ value = values + desc_idx;
+ ret = _ecore_getopt_desc_handle(parser, desc, value, arg_val);
+ if ((!ret) && parser->strict)
+ return 0;
+
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_arg_short(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc __UNUSED__, char **argv, int *idx, int *nonargs, const char *arg)
+{
+ int run = 1;
+ while (run && (arg[0] != '\0'))
+ {
+ int opt = arg[0];
+ const Ecore_Getopt_Desc *desc;
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ const char *arg_val;
+ int desc_idx;
+ Ecore_Getopt_Value *value;
+ unsigned char ret;
+
+ desc = _ecore_getopt_parse_find_short(parser, arg[0]);
+ if (!desc)
+ {
+ fprintf
+ (stderr, _("ERROR: unknown option -%c, ignored.\n"), arg[0]);
+ if (parser->strict)
+ return 0;
+
+ arg++;
+ continue;
+ }
+
+ arg++;
+
+ arg_req = _ecore_getopt_desc_arg_requirement(desc);
+ if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
+ {
+ (*idx)++;
+ run = 0;
+
+ if (arg[0] == '=')
+ arg_val = arg + 1;
+ else if (arg[0] != '\0')
+ arg_val = arg;
+ else
+ {
+ if ((*idx < *nonargs) && (argv[*idx][0] != '-'))
+ {
+ arg_val = argv[*idx];
+ (*idx)++;
+ }
+ else
+ arg_val = NULL;
+ }
+
+ if (arg_val && arg_val[0] == '\0')
+ arg_val = NULL;
+
+ if ((!arg_val) &&
+ (arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES))
+ {
+ fprintf
+ (stderr, _("ERROR: option -%c requires an argument!\n"),
+ opt);
+ if (parser->strict)
+ return 0;
+ return 1;
+ }
+ }
+ else
+ arg_val = NULL;
+
+ desc_idx = desc - parser->descs;
+ value = values + desc_idx;
+ ret = _ecore_getopt_desc_handle(parser, desc, value, arg_val);
+ if ((!ret) && parser->strict)
+ return 0;
+ }
+
+ if (run)
+ (*idx)++;
+
+ return 1;
+}
+
+static unsigned char
+_ecore_getopt_parse_arg(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc, char **argv, int *idx, int *nonargs)
+{
+ char *arg = argv[*idx];
+
+ if (arg[0] != '-')
+ {
+ char **dst, **src, **src_end;
+
+ dst = argv + *idx;
+ src = dst + 1;
+ src_end = src + *nonargs - *idx - 1;
+
+ for (; src < src_end; src++, dst++)
+ *dst = *src;
+
+ *dst = arg;
+ (*nonargs)--;
+ return 1;
+ }
+
+ if (arg[1] == '-')
+ return _ecore_getopt_parse_arg_long
+ (parser, values, argc, argv, idx, nonargs, arg + 2);
+ else
+ return _ecore_getopt_parse_arg_short
+ (parser, values, argc, argv, idx, nonargs, arg + 1);
+}
+
+static const Ecore_Getopt_Desc *
+_ecore_getopt_parse_find_short_other(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *orig)
+{
+ const Ecore_Getopt_Desc *desc = parser->descs;
+ const char c = orig->shortname;
+
+ for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
+ {
+ if (desc == orig)
+ return NULL;
+
+ if (c == desc->shortname)
+ return desc;
+ }
+
+ return NULL;
+}
+
+static const Ecore_Getopt_Desc *
+_ecore_getopt_parse_find_long_other(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *orig)
+{
+ const Ecore_Getopt_Desc *desc = parser->descs;
+ const char *name = orig->longname;
+
+ for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
+ {
+ if (desc == orig)
+ return NULL;
+
+ if (desc->longname && (strcmp(name, desc->longname) == 0))
+ return desc;
+ }
+
+ return NULL;
+}
+
+/**
+ * Check parser for duplicate entries, print them out.
+ *
+ * @return 1 if there are duplicates, 0 otherwise.
+ */
+unsigned char
+ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser)
+{
+ const Ecore_Getopt_Desc *desc = parser->descs;
+ for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
+ {
+ if (desc->shortname)
+ {
+ const Ecore_Getopt_Desc *other;
+ other = _ecore_getopt_parse_find_short_other(parser, desc);
+ if (other)
+ {
+ _ecore_getopt_desc_print_error
+ (desc, "short name -%c already exists.", desc->shortname);
+
+ if (other->longname)
+ fprintf(stderr, " Other is --%s.\n", other->longname);
+ else
+ fputc('\n', stderr);
+ return 1;
+ }
+ }
+
+ if (desc->longname)
+ {
+ const Ecore_Getopt_Desc *other;
+ other = _ecore_getopt_parse_find_long_other(parser, desc);
+ if (other)
+ {
+ _ecore_getopt_desc_print_error
+ (desc, "long name --%s already exists.", desc->longname);
+
+ if (other->shortname)
+ fprintf(stderr, " Other is -%c.\n", other->shortname);
+ else
+ fputc('\n', stderr);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static const Ecore_Getopt_Desc *
+_ecore_getopt_find_help(const Ecore_Getopt *parser)
+{
+ const Ecore_Getopt_Desc *desc = parser->descs;
+ for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
+ if (desc->action == ECORE_GETOPT_ACTION_HELP)
+ return desc;
+ return NULL;
+}
+
+/**
+ * Parse command line parameters.
+ *
+ * Walks the command line parameters and parse them based on @a parser
+ * description, doing actions based on @c parser->descs->action, like
+ * showing help text, license, copyright, storing values in values and
+ * so on.
+ *
+ * It is expected that values is of the same size than @c parser->descs,
+ * options that do not need a value it will be left untouched.
+ *
+ * All values are expected to be initialized before use. Options with
+ * action @c ECORE_GETOPT_ACTION_STORE and non required arguments
+ * (others than @c ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES), are expected
+ * to provide a value in @c def to be used.
+ *
+ * The following actions will store 1 on value as a boolean
+ * (@c value->boolp) if it's not NULL to indicate these actions were executed:
+ * - @c ECORE_GETOPT_ACTION_HELP
+ * - @c ECORE_GETOPT_ACTION_VERSION
+ * - @c ECORE_GETOPT_ACTION_COPYRIGHT
+ * - @c ECORE_GETOPT_ACTION_LICENSE
+ *
+ * Just @c ECORE_GETOPT_ACTION_APPEND will allocate memory and thus
+ * need to be freed. For consistency between all of appended subtypes,
+ * @c eina_list->data will contain an allocated memory with the value,
+ * that is, for @c ECORE_GETOPT_TYPE_STR it will contain a copy of the
+ * argument, @c ECORE_GETOPT_TYPE_INT a pointer to an allocated
+ * integer and so on.
+ *
+ * If parser is in strict mode (see @c Ecore_Getopt->strict), then any
+ * error will abort parsing and -1 is returned. Otherwise it will try
+ * to continue as far as possible.
+ *
+ * This function may reorder @a argv elements.
+ *
+ * Translation of help strings (description), metavar, usage, license
+ * and copyright may be translated, standard/global gettext() call
+ * will be applied on them if ecore was compiled with such support.
+ *
+ * @param parser description of how to work.
+ * @param value where to store values, it is assumed that this is a vector
+ * of the same size as @c parser->descs. Values should be previously
+ * initialized.
+ * @param argc how many elements in @a argv. If not provided it will be
+ * retrieved with ecore_app_args_get().
+ * @param argv command line parameters.
+ *
+ * @return index of first non-option parameter or -1 on error.
+ */
+int
+ecore_getopt_parse(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc, char **argv)
+{
+ int i, nonargs;
+
+ if (!parser)
+ {
+ fputs(_("ERROR: no parser provided.\n"), stderr);
+ return -1;
+ }
+ if (!values)
+ {
+ fputs(_("ERROR: no values provided.\n"), stderr);
+ return -1;
+ }
+
+ if ((argc < 1) || (argv == NULL))
+ ecore_app_args_get(&argc, &argv);
+
+ if (argc < 1)
+ {
+ fputs(_("ERROR: no arguments provided.\n"), stderr);
+ return -1;
+ }
+
+ if (argv[0] != NULL)
+ prog = argv[0];
+ else
+ prog = parser->prog;
+
+ nonargs = _ecore_getopt_parse_find_nonargs_base(parser, argc, argv);
+ if (nonargs < 0)
+ goto error;
+
+ if (nonargs > argc)
+ nonargs = argc;
+
+ i = 1;
+ while (i < nonargs)
+ if (!_ecore_getopt_parse_arg(parser, values, argc, argv, &i, &nonargs))
+ goto error;
+
+ return nonargs;
+
+ error:
+ {
+ const Ecore_Getopt_Desc *help;
+ fputs(_("ERROR: invalid options found."), stderr);
+
+ help = _ecore_getopt_find_help(parser);
+ if (!help)
+ fputc('\n', stderr);
+ else if (help->longname)
+ fprintf(stderr, _(" See --%s.\n"), help->longname);
+ else
+ fprintf(stderr, _(" See -%c.\n"), help->shortname);
+ }
+
+ return -1;
+}
+
+/**
+ * Utility to free list and nodes allocated by @a ECORE_GETOPT_ACTION_APPEND.
+ *
+ * @param list pointer to list to be freed.
+ * @return always NULL, so you can easily make your list head NULL.
+ */
+Eina_List *
+ecore_getopt_list_free(Eina_List *list)
+{
+ void *data;
+
+ EINA_LIST_FREE(list, data)
+ free(data);
+ return NULL;
+}
+
+/**
+ * Helper ecore_getopt callback to parse geometry (x:y:w:h).
+ *
+ * Storage must be a pointer to @c Eina_Rectangle and will be used to
+ * store the four values passed in the given string.
+ *
+ * @c callback_data value is ignored, you can safely use @c NULL.
+ */
+unsigned char
+ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc __UNUSED__, const char *str, void *data __UNUSED__, Ecore_Getopt_Value *storage)
+{
+ Eina_Rectangle *v = (Eina_Rectangle *)storage->ptrp;
+
+ if (sscanf(str, "%d:%d:%d:%d", &v->x, &v->y, &v->w, &v->h) != 4)
+ {
+ fprintf(stderr, _("ERROR: incorrect geometry value '%s'\n"), str);
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Helper ecore_getopt callback to parse geometry size (WxH).
+ *
+ * Storage must be a pointer to @c Eina_Rectangle and will be used to
+ * store the two values passed in the given string and 0 in the x and y
+ * fields.
+ *
+ * @c callback_data value is ignored, you can safely use @c NULL.
+ */
+unsigned char
+ecore_getopt_callback_size_parse(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc __UNUSED__, const char *str, void *data __UNUSED__, Ecore_Getopt_Value *storage)
+{
+ Eina_Rectangle *v = (Eina_Rectangle *)storage->ptrp;
+
+ if (sscanf(str, "%dx%d", &v->w, &v->h) != 2)
+ {
+ fprintf(stderr, _("ERROR: incorrect size value '%s'\n"), str);
+ return 0;
+ }
+ v->x = 0;
+ v->y = 0;
+
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#ifdef HAVE_GLIB
+#include <glib.h>
+
+static Eina_Bool _ecore_glib_active = EINA_FALSE;
+static int (*_ecore_glib_select_original)(int, fd_set*, fd_set*, fd_set*, struct timeval *);
+static GCond *_ecore_glib_cond = NULL;
+static GPollFD *_ecore_glib_fds = NULL;
+static size_t _ecore_glib_fds_size = 0;
+static const size_t ECORE_GLIB_FDS_INITIAL = 128;
+static const size_t ECORE_GLIB_FDS_STEP = 8;
+static const size_t ECORE_GLIB_FDS_MAX_FREE = 256;
+
+static Eina_Bool
+_ecore_glib_fds_resize(size_t size)
+{
+ void *tmp = realloc(_ecore_glib_fds, sizeof(GPollFD) * size);
+
+ if (!tmp)
+ {
+ ERR("Could not realloc from %zu to %zu buckets.",
+ _ecore_glib_fds_size, size);
+ return EINA_FALSE;
+ }
+
+ _ecore_glib_fds = tmp;
+ _ecore_glib_fds_size = size;
+ return EINA_TRUE;
+}
+
+static int
+_ecore_glib_context_query(GMainContext *ctx, int priority, int *p_timer)
+{
+ int reqfds;
+
+ if (_ecore_glib_fds_size == 0)
+ {
+ if (!_ecore_glib_fds_resize(ECORE_GLIB_FDS_INITIAL)) return -1;
+ }
+
+ while (1)
+ {
+ size_t size;
+
+ reqfds = g_main_context_query
+ (ctx, priority, p_timer, _ecore_glib_fds, _ecore_glib_fds_size);
+ if (reqfds <= (int)_ecore_glib_fds_size) break;
+
+ size = (1 + reqfds / ECORE_GLIB_FDS_STEP) * ECORE_GLIB_FDS_STEP;
+ if (!_ecore_glib_fds_resize(size)) return -1;
+ }
+
+ if (reqfds + ECORE_GLIB_FDS_MAX_FREE < _ecore_glib_fds_size)
+ {
+ size_t size;
+
+ size = (1 + reqfds / ECORE_GLIB_FDS_MAX_FREE) * ECORE_GLIB_FDS_MAX_FREE;
+ _ecore_glib_fds_resize(size);
+ }
+
+ return reqfds;
+}
+
+static int
+_ecore_glib_context_poll_from(const GPollFD *pfds, int count, fd_set *rfds, fd_set *wfds, fd_set *efds)
+{
+ const GPollFD *itr = pfds, *itr_end = pfds + count;
+ int glib_fds = -1;
+
+ for (; itr < itr_end; itr++)
+ {
+ if (glib_fds < itr->fd)
+ glib_fds = itr->fd;
+
+ if (itr->events & G_IO_IN)
+ FD_SET(itr->fd, rfds);
+ if (itr->events & G_IO_OUT)
+ FD_SET(itr->fd, wfds);
+ if (itr->events & (G_IO_HUP | G_IO_ERR))
+ FD_SET(itr->fd, efds);
+ }
+
+ return glib_fds + 1;
+}
+
+static int
+_ecore_glib_context_poll_to(GPollFD *pfds, int count, const fd_set *rfds, const fd_set *wfds, const fd_set *efds, int ready)
+{
+ GPollFD *itr = pfds, *itr_end = pfds + count;
+
+ for (; itr < itr_end && ready > 0; itr++)
+ {
+ itr->revents = 0;
+ if (FD_ISSET(itr->fd, rfds))
+ {
+ itr->revents |= G_IO_IN;
+ ready--;
+ }
+ if (FD_ISSET(itr->fd, wfds))
+ {
+ itr->revents |= G_IO_OUT;
+ ready--;
+ }
+ if (FD_ISSET(itr->fd, efds))
+ {
+ itr->revents |= G_IO_ERR;
+ ready--;
+ }
+ }
+ return ready;
+}
+
+static int
+_ecore_glib_select__locked(GMainContext *ctx, int ecore_fds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *ecore_timeout)
+{
+ int priority, maxfds, glib_fds, reqfds, reqtimeout, ret;
+ struct timeval *timeout, glib_timeout;
+
+ g_main_context_prepare(ctx, &priority);
+ reqfds = _ecore_glib_context_query(ctx, priority, &reqtimeout);
+ if (reqfds < 0) goto error;
+
+ glib_fds = _ecore_glib_context_poll_from
+ (_ecore_glib_fds, reqfds, rfds, wfds, efds);
+
+ if (reqtimeout == -1)
+ timeout = ecore_timeout;
+ else
+ {
+ glib_timeout.tv_sec = reqtimeout / 1000;
+ glib_timeout.tv_usec = (reqtimeout % 1000) * 1000;
+
+ if (!ecore_timeout || timercmp(ecore_timeout, &glib_timeout, >))
+ timeout = &glib_timeout;
+ else
+ timeout = ecore_timeout;
+ }
+
+ maxfds = (ecore_fds >= glib_fds) ? ecore_fds : glib_fds;
+ ret = _ecore_glib_select_original(maxfds, rfds, wfds, efds, timeout);
+
+ ret = _ecore_glib_context_poll_to
+ (_ecore_glib_fds, reqfds, rfds, wfds, efds, ret);
+
+ if (g_main_context_check(ctx, priority, _ecore_glib_fds, reqfds))
+ g_main_context_dispatch(ctx);
+
+ return ret;
+
+ error:
+ return _ecore_glib_select_original
+ (ecore_fds, rfds, wfds, efds, ecore_timeout);
+}
+
+static int
+_ecore_glib_select(int ecore_fds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *ecore_timeout)
+{
+ GStaticMutex lock = G_STATIC_MUTEX_INIT;
+ GMutex *mutex = g_static_mutex_get_mutex(&lock);
+ GMainContext *ctx = g_main_context_default();
+ int ret;
+
+ if (g_main_context_acquire(ctx))
+ g_mutex_lock(mutex);
+ else
+ {
+ if (!_ecore_glib_cond)
+ _ecore_glib_cond = g_cond_new();
+
+ while (!g_main_context_wait(ctx, _ecore_glib_cond, mutex))
+ g_thread_yield();
+ }
+
+ ret = _ecore_glib_select__locked
+ (ctx, ecore_fds, rfds, wfds, efds, ecore_timeout);
+
+ g_mutex_unlock(mutex);
+ g_main_context_release(ctx);
+
+ return ret;
+}
+#endif
+
+void
+_ecore_glib_init(void)
+{
+}
+
+void
+_ecore_glib_shutdown(void)
+{
+#ifdef HAVE_GLIB
+ if (!_ecore_glib_active) return;
+ _ecore_glib_active = EINA_FALSE;
+
+ if (ecore_main_loop_select_func_get() == _ecore_glib_select)
+ ecore_main_loop_select_func_set(_ecore_glib_select_original);
+
+ if (_ecore_glib_fds)
+ {
+ free(_ecore_glib_fds);
+ _ecore_glib_fds = NULL;
+ }
+ _ecore_glib_fds_size = 0;
+
+ if (_ecore_glib_cond)
+ {
+ g_cond_free(_ecore_glib_cond);
+ _ecore_glib_cond = NULL;
+ }
+#endif
+}
+
+/**
+ * Request ecore to integrate GLib's main loop.
+ *
+ * This will add a small overhead during every main loop interaction
+ * by checking glib's default main context (used by its main loop). If
+ * it have events to be checked (timers, file descriptors or idlers),
+ * then these will be polled alongside with Ecore's own events, then
+ * dispatched before Ecore's. This is done by calling
+ * ecore_main_loop_select_func_set().
+ *
+ * This will cooperate with previously set
+ * ecore_main_loop_select_func_set() by calling the old
+ * function. Similarly, if you want to override
+ * ecore_main_loop_select_func_set() after main loop is integrated,
+ * call the new select function set by this call (get it by calling
+ * ecore_main_loop_select_func_get() right after
+ * ecore_main_loop_glib_integrate()).
+ *
+ * This is useful to use GMainLoop libraries, like GTK, GUPnP,
+ * LibSoup, GConf and more. Adobe Flash plugin and other plugins
+ * systems depend on this as well.
+ *
+ * Once initialized/integrated, it will be valid until Ecore is
+ * completely shut down.
+ *
+ * @note this is only available if Ecore was compiled with GLib support.
+ *
+ * @return @c EINA_TRUE on success of @c EINA_FALSE if it failed,
+ * likely no GLib support in Ecore.
+ */
+EAPI Eina_Bool
+ecore_main_loop_glib_integrate(void)
+{
+#ifdef HAVE_GLIB
+ void *func;
+
+ if (_ecore_glib_active) return EINA_TRUE;
+ func = ecore_main_loop_select_func_get();
+ if (func == _ecore_glib_select) return EINA_TRUE;
+ _ecore_glib_select_original = func;
+ ecore_main_loop_select_func_set(_ecore_glib_select);
+ _ecore_glib_active = EINA_TRUE;
+ return EINA_TRUE;
+#else
+ fputs("ERROR: no glib support in ecore.\n", stderr);
+ return EINA_FALSE;
+#endif
+}
+
+Eina_Bool _ecore_glib_always_integrate = 1;
+
+/**
+ * Disable always integrating glib
+ *
+ * If ecore is compiled with --enable-glib-integration-always (to always
+ * call ecore_main_loop_glib_integrate() when ecore_init() is called), then
+ * calling this before calling ecore_init() will disable the integration.
+ * This is for apps that explicitly do not want this to happen for whatever
+ * reasons they may have.
+ */
+EAPI void
+ecore_main_loop_glib_always_integrate_disable(void)
+{
+ _ecore_glib_always_integrate = 0;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Idle_Enterer
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ int (*func) (void *data);
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
+};
+
+
+static Ecore_Idle_Enterer *idle_enterers = NULL;
+static Ecore_Idle_Enterer *idle_enterer_current = NULL;
+static int idle_enterers_delete_me = 0;
+
+/**
+ * Add an idle enterer handler.
+ * @param func The function to call when entering an idle state.
+ * @param data The data to be passed to the @p func call
+ * @return A handle to the idle enterer callback if successful. Otherwise,
+ * NULL is returned.
+ * @ingroup Idle_Group
+ */
+EAPI Ecore_Idle_Enterer *
+ecore_idle_enterer_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Idle_Enterer *ie;
+
+ if (!func) return NULL;
+ ie = calloc(1, sizeof(Ecore_Idle_Enterer));
+ if (!ie) return NULL;
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
+ ie->func = func;
+ ie->data = (void *)data;
+ idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+ return ie;
+}
+
+/**
+ * Add an idle enterer handler at the start of the list so it gets called earlier than others.
+ * @param func The function to call when entering an idle state.
+ * @param data The data to be passed to the @p func call
+ * @return A handle to the idle enterer callback if successful. Otherwise,
+ * NULL is returned.
+ * @ingroup Idle_Group
+ */
+EAPI Ecore_Idle_Enterer *
+ecore_idle_enterer_before_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Idle_Enterer *ie;
+
+ if (!func) return NULL;
+ ie = calloc(1, sizeof(Ecore_Idle_Enterer));
+ if (!ie) return NULL;
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
+ ie->func = func;
+ ie->data = (void *)data;
+ idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+ return ie;
+}
+
+/**
+ * Delete an idle enterer callback.
+ * @param idle_enterer The idle enterer to delete
+ * @return The data pointer passed to the idler enterer callback on success.
+ * NULL otherwise.
+ * @ingroup Idle_Group
+ */
+EAPI void *
+ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
+{
+ if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER))
+ {
+ ECORE_MAGIC_FAIL(idle_enterer, ECORE_MAGIC_IDLE_ENTERER,
+ "ecore_idle_enterer_del");
+ return NULL;
+ }
+ idle_enterer->delete_me = 1;
+ idle_enterers_delete_me = 1;
+ return idle_enterer->data;
+}
+
+void
+_ecore_idle_enterer_shutdown(void)
+{
+ Ecore_Idle_Enterer *ie;
+ while ((ie = idle_enterers))
+ {
+ idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ idle_enterers_delete_me = 0;
+ idle_enterer_current = NULL;
+}
+
+void
+_ecore_idle_enterer_call(void)
+{
+ if (!idle_enterer_current)
+ {
+ /* regular main loop, start from head */
+ idle_enterer_current = idle_enterers;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ idle_enterer_current =
+ (Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
+ }
+
+ while (idle_enterer_current)
+ {
+ Ecore_Idle_Enterer *ie = (Ecore_Idle_Enterer *)idle_enterer_current;
+ if (!ie->delete_me)
+ {
+ ie->references++;
+ if (!ie->func(ie->data)) ecore_idle_enterer_del(ie);
+ ie->references--;
+ }
+ if (idle_enterer_current) /* may have changed in recursive main loops */
+ idle_enterer_current =
+ (Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
+ }
+ if (idle_enterers_delete_me)
+ {
+ Ecore_Idle_Enterer *l;
+ int deleted_idler_enterers_in_use = 0;
+
+ for (l = idle_enterers; l;)
+ {
+ Ecore_Idle_Enterer *ie = l;
+ l = (Ecore_Idle_Enterer *) EINA_INLIST_GET(l)->next;
+ if (ie->delete_me)
+ {
+ if (ie->references)
+ {
+ deleted_idler_enterers_in_use++;
+ continue;
+ }
+
+ idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ }
+ if (!deleted_idler_enterers_in_use)
+ idle_enterers_delete_me = 0;
+ }
+}
+
+int
+_ecore_idle_enterer_exist(void)
+{
+ if (idle_enterers) return 1;
+ return 0;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Idle_Exiter
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ int (*func) (void *data);
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
+};
+
+
+static Ecore_Idle_Exiter *idle_exiters = NULL;
+static Ecore_Idle_Exiter *idle_exiter_current = NULL;
+static int idle_exiters_delete_me = 0;
+
+/**
+ * Add an idle exiter handler.
+ * @param func The function to call when exiting an idle state.
+ * @param data The data to be passed to the @p func call
+ * @return A handle to the idle exiter callback on success. NULL otherwise.
+ * @ingroup Idle_Group
+ */
+EAPI Ecore_Idle_Exiter *
+ecore_idle_exiter_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Idle_Exiter *ie;
+
+ if (!func) return NULL;
+ ie = calloc(1, sizeof(Ecore_Idle_Exiter));
+ if (!ie) return NULL;
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER);
+ ie->func = func;
+ ie->data = (void *)data;
+ idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
+ return ie;
+}
+
+/**
+ * Delete an idle exiter handler from the list to be run on exiting idle state.
+ * @param idle_exiter The idle exiter to delete
+ * @return The data pointer that was being being passed to the handler if
+ * successful. NULL otherwise.
+ * @ingroup Idle_Group
+ */
+EAPI void *
+ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
+{
+ if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER))
+ {
+ ECORE_MAGIC_FAIL(idle_exiter, ECORE_MAGIC_IDLE_EXITER,
+ "ecore_idle_exiter_del");
+ return NULL;
+ }
+ idle_exiter->delete_me = 1;
+ idle_exiters_delete_me = 1;
+ return idle_exiter->data;
+}
+
+void
+_ecore_idle_exiter_shutdown(void)
+{
+ Ecore_Idle_Exiter *ie;
+ while ((ie = idle_exiters))
+ {
+ idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters));
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ idle_exiters_delete_me = 0;
+ idle_exiter_current = NULL;
+}
+
+void
+_ecore_idle_exiter_call(void)
+{
+ if (!idle_exiter_current)
+ {
+ /* regular main loop, start from head */
+ idle_exiter_current = idle_exiters;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ idle_exiter_current =
+ (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
+ }
+
+ while (idle_exiter_current)
+ {
+ Ecore_Idle_Exiter *ie = (Ecore_Idle_Exiter *)idle_exiter_current;
+ if (!ie->delete_me)
+ {
+ ie->references++;
+ if (!ie->func(ie->data)) ecore_idle_exiter_del(ie);
+ ie->references--;
+ }
+ if (idle_exiter_current) /* may have changed in recursive main loops */
+ idle_exiter_current =
+ (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
+ }
+ if (idle_exiters_delete_me)
+ {
+ Ecore_Idle_Exiter *l;
+ int deleted_idler_exiters_in_use = 0;
+
+ for (l = idle_exiters; l;)
+ {
+ Ecore_Idle_Exiter *ie = l;
+
+ l = (Ecore_Idle_Exiter *) EINA_INLIST_GET(l)->next;
+ if (ie->delete_me)
+ {
+ if (ie->references)
+ {
+ deleted_idler_exiters_in_use++;
+ continue;
+ }
+
+ idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ }
+ if (!deleted_idler_exiters_in_use)
+ idle_exiters_delete_me = 0;
+ }
+}
+
+int
+_ecore_idle_exiter_exist(void)
+{
+ if (idle_exiters) return 1;
+ return 0;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Idler
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ int (*func) (void *data);
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
+};
+
+
+static Ecore_Idler *idlers = NULL;
+static Ecore_Idler *idler_current = NULL;
+static int idlers_delete_me = 0;
+
+/**
+ * Add an idler handler.
+ * @param func The function to call when idling.
+ * @param data The data to be passed to this @p func call.
+ * @return A idler handle if successfully added. NULL otherwise.
+ * @ingroup Idle_Group
+ *
+ * Add an idler handle to the event loop, returning a handle on success and
+ * NULL otherwise. The function @p func will be called repeatedly while
+ * no other events are ready to be processed, as long as it returns 1
+ * (or ECORE_CALLBACK_RENEW). A return of 0 (or ECORE_CALLBACK_CANCEL) deletes
+ * the idler.
+ *
+ * Idlers are useful for progressively prossessing data without blocking.
+ */
+EAPI Ecore_Idler *
+ecore_idler_add(int (*func) (void *data), const void *data)
+{
+ Ecore_Idler *ie;
+
+ if (!func) return NULL;
+ ie = calloc(1, sizeof(Ecore_Idler));
+ if (!ie) return NULL;
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER);
+ ie->func = func;
+ ie->data = (void *)data;
+ idlers = (Ecore_Idler *) eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
+ return ie;
+}
+
+/**
+ * Delete an idler callback from the list to be executed.
+ * @param idler The handle of the idler callback to delete
+ * @return The data pointer passed to the idler callback on success. NULL
+ * otherwise.
+ * @ingroup Idle_Group
+ */
+EAPI void *
+ecore_idler_del(Ecore_Idler *idler)
+{
+ if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER))
+ {
+ ECORE_MAGIC_FAIL(idler, ECORE_MAGIC_IDLER,
+ "ecore_idler_del");
+ return NULL;
+ }
+ idler->delete_me = 1;
+ idlers_delete_me = 1;
+ return idler->data;
+}
+
+void
+_ecore_idler_shutdown(void)
+{
+ Ecore_Idler *ie;
+ while ((ie = idlers))
+ {
+ idlers = (Ecore_Idler *) eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers));
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ idlers_delete_me = 0;
+ idler_current = NULL;
+}
+
+int
+_ecore_idler_call(void)
+{
+ if (!idler_current)
+ {
+ /* regular main loop, start from head */
+ idler_current = idlers;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next;
+ }
+
+ while (idler_current)
+ {
+ Ecore_Idler *ie = (Ecore_Idler *)idler_current;
+ if (!ie->delete_me)
+ {
+ ie->references++;
+ if (!ie->func(ie->data)) ecore_idler_del(ie);
+ ie->references--;
+ }
+ if (idler_current) /* may have changed in recursive main loops */
+ idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next;
+ }
+ if (idlers_delete_me)
+ {
+ Ecore_Idler *l;
+ int deleted_idlers_in_use = 0;
+ for (l = idlers; l;)
+ {
+ Ecore_Idler *ie = l;
+ l = (Ecore_Idler *) EINA_INLIST_GET(l)->next;
+ if (ie->delete_me)
+ {
+ if (ie->references)
+ {
+ deleted_idlers_in_use++;
+ continue;
+ }
+
+ idlers = (Ecore_Idler *) eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
+ ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
+ free(ie);
+ }
+ }
+ if (!deleted_idlers_in_use)
+ idlers_delete_me = 0;
+ }
+ if (idlers) return 1;
+ return 0;
+}
+
+int
+_ecore_idler_exist(void)
+{
+ if (idlers) return 1;
+ return 0;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+static int _ecore_job_event_handler(void *data, int type, void *ev);
+static void _ecore_job_event_free(void *data, void *ev);
+
+static int ecore_event_job_type = 0;
+static Ecore_Event_Handler* _ecore_job_handler = NULL;
+
+struct _Ecore_Job
+{
+ ECORE_MAGIC;
+ Ecore_Event *event;
+ void (*func) (void *data);
+ void *data;
+};
+
+void
+_ecore_job_init(void)
+{
+ ecore_event_job_type = ecore_event_type_new();
+ _ecore_job_handler = ecore_event_handler_add(ecore_event_job_type, _ecore_job_event_handler, NULL);
+}
+
+void
+_ecore_job_shutdown(void)
+{
+ ecore_event_handler_del(_ecore_job_handler);
+ _ecore_job_handler = NULL;
+}
+
+/**
+ * Add a job to the event queue.
+ * @param func The function to call when the job gets handled.
+ * @param data Data pointer to be passed to the job function when the job is
+ * handled.
+ * @return The handle of the job. @c NULL is returned if the job could not be
+ * added to the queue.
+ * @ingroup Ecore_Job_Group
+ * @note Once the job has been executed, the job handle is invalid.
+ */
+EAPI Ecore_Job *
+ecore_job_add(void (*func) (void *data), const void *data)
+{
+ Ecore_Job *job;
+
+ if (!func) return NULL;
+
+ job = calloc(1, sizeof(Ecore_Job));
+ if (!job) return NULL;
+ ECORE_MAGIC_SET(job, ECORE_MAGIC_JOB);
+ job->event = ecore_event_add(ecore_event_job_type, job, _ecore_job_event_free, NULL);
+ if (!job->event)
+ {
+ free(job);
+ return NULL;
+ }
+ job->func = func;
+ job->data = (void *)data;
+ return job;
+}
+
+/**
+ * Delete a queued job that has not yet been executed.
+ * @param job Handle of the job to delete.
+ * @return The data pointer that was to be passed to the job.
+ * @ingroup Ecore_Job_Group
+ */
+EAPI void *
+ecore_job_del(Ecore_Job *job)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_JOB))
+ {
+ ECORE_MAGIC_FAIL(job, ECORE_MAGIC_JOB,
+ "ecore_job_del");
+ return NULL;
+ }
+ data = job->data;
+ ECORE_MAGIC_SET(job, ECORE_MAGIC_NONE);
+ ecore_event_del(job->event);
+ return data;
+}
+
+static int
+_ecore_job_event_handler(void *data __UNUSED__, int type __UNUSED__, void *ev)
+{
+ Ecore_Job *job;
+
+ job = ev;
+ job->func(job->data);
+ return 0;
+}
+
+static void
+_ecore_job_event_free(void *data __UNUSED__, void *ev)
+{
+ free(ev);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <winsock2.h>
+# undef WIN32_LEAN_AND_MEAN
+# ifndef USER_TIMER_MINIMUM
+# define USER_TIMER_MINIMUM 0x0a
+# endif
+#endif
+
+#ifdef __SUNPRO_C
+# include <ieeefp.h>
+# include <string.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifndef _MSC_VER
+#include <sys/time.h>
+# include <unistd.h>
+#else
+# include <float.h>
+#endif
+
+#define FIX_HZ 1
+
+#ifdef FIX_HZ
+# ifndef _MSC_VER
+# include <sys/param.h>
+# endif
+# ifndef HZ
+# define HZ 100
+# endif
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Fd_Handler
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ int fd;
+ Ecore_Fd_Handler_Flags flags;
+ int (*func) (void *data, Ecore_Fd_Handler *fd_handler);
+ void *data;
+ int (*buf_func) (void *data, Ecore_Fd_Handler *fd_handler);
+ void *buf_data;
+ void (*prep_func) (void *data, Ecore_Fd_Handler *fd_handler);
+ void *prep_data;
+ int references;
+ Eina_Bool read_active : 1;
+ Eina_Bool write_active : 1;
+ Eina_Bool error_active : 1;
+ Eina_Bool delete_me : 1;
+};
+
+#ifdef _WIN32
+struct _Ecore_Win32_Handler
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ HANDLE h;
+ int (*func) (void *data, Ecore_Win32_Handler *win32_handler);
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
+};
+#endif
+
+
+static int _ecore_main_select(double timeout);
+static void _ecore_main_fd_handlers_cleanup(void);
+#ifndef _WIN32
+static void _ecore_main_fd_handlers_bads_rem(void);
+#endif
+static void _ecore_main_fd_handlers_call(void);
+static int _ecore_main_fd_handlers_buf_call(void);
+static void _ecore_main_loop_iterate_internal(int once_only);
+
+#ifdef _WIN32
+static int _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout);
+static void _ecore_main_win32_handlers_cleanup(void);
+#endif
+
+static int in_main_loop = 0;
+static int do_quit = 0;
+static Ecore_Fd_Handler *fd_handlers = NULL;
+static Ecore_Fd_Handler *fd_handler_current = NULL;
+static int fd_handlers_delete_me = 0;
+#ifdef _WIN32
+static Ecore_Win32_Handler *win32_handlers = NULL;
+static Ecore_Win32_Handler *win32_handler_current = NULL;
+static int win32_handlers_delete_me = 0;
+#endif
+
+#ifdef _WIN32
+static int (*main_loop_select)(int , fd_set *, fd_set *, fd_set *, struct timeval *) = _ecore_main_win32_select;
+#else
+static int (*main_loop_select)(int , fd_set *, fd_set *, fd_set *, struct timeval *) = select;
+#endif
+
+static double t1 = 0.0;
+static double t2 = 0.0;
+
+/**
+ * @defgroup Ecore_Main_Loop_Group Main Loop Functions
+ *
+ * These functions control the Ecore event handling loop. This loop is
+ * designed to work on embedded systems all the way to large and
+ * powerful mutli-cpu workstations.
+ *
+ * It serialises all system signals and events into a single event
+ * queue, that can be easily processed without needing to worry about
+ * concurrency. A properly written, event-driven program using this
+ * kind of programming does not need threads. It makes the program very
+ * robust and easy to follow.
+ *
+ * Here is an example of simple program and its basic event loop flow:
+ * @image html prog_flow.png
+ *
+ * For examples of setting up and using a main loop, see
+ * @ref event_handler_example.c and @ref timer_example.c.
+ */
+
+/**
+ * Runs a single iteration of the main loop to process everything on the
+ * queue.
+ * @ingroup Ecore_Main_Loop_Group
+ */
+EAPI void
+ecore_main_loop_iterate(void)
+{
+ _ecore_main_loop_iterate_internal(1);
+}
+
+/**
+ * Runs the application main loop.
+ *
+ * This function will not return until @ref ecore_main_loop_quit is called.
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ */
+EAPI void
+ecore_main_loop_begin(void)
+{
+ in_main_loop++;
+ for (;do_quit == 0;) _ecore_main_loop_iterate_internal(0);
+ do_quit = 0;
+ in_main_loop--;
+}
+
+/**
+ * Quits the main loop once all the events currently on the queue have
+ * been processed.
+ * @ingroup Ecore_Main_Loop_Group
+ */
+EAPI void
+ecore_main_loop_quit(void)
+{
+ do_quit = 1;
+}
+
+/**
+ * Sets the function to use when monitoring multiple file descriptors,
+ * and waiting until one of more of the file descriptors before ready
+ * for some class of I/O operation.
+ *
+ * This function will be used instead of the system call select and
+ * could possible be used to integrate the Ecore event loop with an
+ * external event loop.
+ *
+ * @warning you don't know how to use, don't even try to use it.
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ */
+EAPI void
+ecore_main_loop_select_func_set(int (*func)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout))
+{
+ main_loop_select = func;
+}
+
+/**
+ * Gets the select function set by ecore_select_func_set(),
+ * or the native select function if none was set.
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ */
+EAPI void *
+ecore_main_loop_select_func_get(void)
+{
+ return main_loop_select;
+}
+
+/**
+ * @defgroup Ecore_FD_Handler_Group File Event Handling Functions
+ *
+ * Functions that deal with file descriptor handlers.
+ */
+
+/**
+ * Adds a callback for activity on the given file descriptor.
+ *
+ * @p func will be called during the execution of @ref ecore_main_loop_begin
+ * when the file descriptor is available for reading, or writing, or both.
+ *
+ * Normally the return value from the @p func is "zero means this handler is
+ * finished and can be deleted" as is usual for handler callbacks. However,
+ * if the @p buf_func is supplied, then the return value from the @p func is
+ * "non zero means the handler should be called again in a tight loop".
+ *
+ * @p buf_func is called during event loop handling to check if data that has
+ * been read from the file descriptor is in a buffer and is available to
+ * read. Some systems (notably xlib) handle their own buffering, and would
+ * otherwise not work with select(). These systems should use a @p buf_func.
+ * This is a most annoying hack, only ecore_x uses it, so refer to that for
+ * an example. NOTE - @p func should probably return "one" always if
+ * @p buf_func is used, to avoid confusion with the other return value
+ * semantics.
+ *
+ * @param fd The file descriptor to watch.
+ * @param flags To watch it for read (@c ECORE_FD_READ) and/or
+ * (@c ECORE_FD_WRITE) write ability. @c ECORE_FD_ERROR
+ *
+ * @param func The callback function.
+ * @param data The data to pass to the callback.
+ * @param buf_func The function to call to check if any data has been
+ * buffered and already read from the fd. Can be @c NULL.
+ * @param buf_data The data to pass to the @p buf_func function.
+ * @return A fd handler handle if successful. @c NULL otherwise.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+EAPI Ecore_Fd_Handler *
+ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data, int (*buf_func) (void *buf_data, Ecore_Fd_Handler *fd_handler), const void *buf_data)
+{
+ Ecore_Fd_Handler *fdh;
+
+ if ((fd < 0) ||
+ (flags == 0) ||
+ (!func)) return NULL;
+
+ fdh = calloc(1, sizeof(Ecore_Fd_Handler));
+ if (!fdh) return NULL;
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
+ fdh->fd = fd;
+ fdh->flags = flags;
+ fdh->read_active = 0;
+ fdh->write_active = 0;
+ fdh->error_active = 0;
+ fdh->delete_me = 0;
+ fdh->func = func;
+ fdh->data = (void *)data;
+ fdh->buf_func = buf_func;
+ fdh->buf_data = (void *)buf_data;
+ fd_handlers = (Ecore_Fd_Handler *) eina_inlist_append(EINA_INLIST_GET(fd_handlers),
+ EINA_INLIST_GET(fdh));
+ return fdh;
+}
+
+#ifdef _WIN32
+EAPI Ecore_Win32_Handler *
+ecore_main_win32_handler_add(void *h,
+ int (*func) (void *data, Ecore_Win32_Handler *wh),
+ const void *data)
+{
+ Ecore_Win32_Handler *wh;
+
+ if (!h || !func)
+ return NULL;
+
+ wh = calloc(1, sizeof(Ecore_Win32_Handler));
+ if (!wh) return NULL;
+ ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER);
+ wh->h = (HANDLE)h;
+ wh->delete_me = 0;
+ wh->func = func;
+ wh->data = (void *)data;
+ win32_handlers = (Ecore_Win32_Handler *)eina_inlist_append(EINA_INLIST_GET(win32_handlers),
+ EINA_INLIST_GET(wh));
+ return wh;
+}
+#else
+EAPI Ecore_Win32_Handler *
+ecore_main_win32_handler_add(void *h __UNUSED__,
+ int (*func) (void *data, Ecore_Win32_Handler *wh) __UNUSED__,
+ const void *data __UNUSED__)
+{
+ return NULL;
+}
+#endif
+
+/**
+ * Deletes the given FD handler.
+ * @param fd_handler The given FD handler.
+ * @return The data pointer set using @ref ecore_main_fd_handler_add,
+ * for @p fd_handler on success. @c NULL otherwise.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+EAPI void *
+ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_del");
+ return NULL;
+ }
+ fd_handler->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ return fd_handler->data;
+}
+
+#ifdef _WIN32
+EAPI void *
+ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
+{
+ if (!ECORE_MAGIC_CHECK(win32_handler, ECORE_MAGIC_WIN32_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(win32_handler, ECORE_MAGIC_WIN32_HANDLER,
+ "ecore_main_win32_handler_del");
+ return NULL;
+ }
+ win32_handler->delete_me = 1;
+ win32_handlers_delete_me = 1;
+ return win32_handler->data;
+}
+#else
+EAPI void *
+ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
+{
+ return NULL;
+}
+#endif
+
+EAPI void
+ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, void (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_prepare_callback_set");
+ return;
+ }
+ fd_handler->prep_func = func;
+ fd_handler->prep_data = (void *) data;
+}
+
+/**
+ * Retrieves the file descriptor that the given handler is handling.
+ * @param fd_handler The given FD handler.
+ * @return The file descriptor the handler is watching.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+EAPI int
+ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_fd_get");
+ return -1;
+ }
+ return fd_handler->fd;
+}
+
+/**
+ * Return if read, write or error, or a combination thereof, is active on the
+ * file descriptor of the given FD handler.
+ * @param fd_handler The given FD handler.
+ * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or
+ * @c ECORE_FD_ERROR to query.
+ * @return @c 1 if any of the given flags are active. @c 0 otherwise.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+EAPI int
+ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
+{
+ int ret;
+
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_active_get");
+ return 0;
+ }
+ ret = 0;
+ if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = 1;
+ if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = 1;
+ if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = 1;
+ return ret;
+}
+
+/**
+ * Set what active streams the given FD handler should be monitoring.
+ * @param fd_handler The given FD handler.
+ * @param flags The flags to be watching.
+ * @ingroup Ecore_FD_Handler_Group
+ */
+EAPI void
+ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
+{
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_active_set");
+ return;
+ }
+ fd_handler->flags = flags;
+}
+
+void
+_ecore_main_shutdown(void)
+{
+ if (in_main_loop)
+ {
+ ERR("\n"
+ "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
+ "*** Program may crash or behave strangely now.");
+ return;
+ }
+ while (fd_handlers)
+ {
+ Ecore_Fd_Handler *fdh;
+
+ fdh = fd_handlers;
+ fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
+ EINA_INLIST_GET(fdh));
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
+ free(fdh);
+ }
+ fd_handlers_delete_me = 0;
+ fd_handler_current = NULL;
+
+#ifdef _WIN32
+ while (win32_handlers)
+ {
+ Ecore_Win32_Handler *wh;
+
+ wh = win32_handlers;
+ win32_handlers = (Ecore_Win32_Handler *) eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
+ EINA_INLIST_GET(wh));
+ ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
+ free(wh);
+ }
+ win32_handlers_delete_me = 0;
+ win32_handler_current = NULL;
+#endif
+}
+
+static int
+_ecore_main_select(double timeout)
+{
+ struct timeval tv, *t;
+ fd_set rfds, wfds, exfds;
+ int max_fd;
+ int ret;
+ Ecore_Fd_Handler *fdh;
+
+ t = NULL;
+ if ((!finite(timeout)) || (timeout == 0.0)) /* finite() tests for NaN, too big, too small, and infinity. */
+ {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ t = &tv;
+ }
+ else if (timeout > 0.0)
+ {
+ int sec, usec;
+
+#ifdef FIX_HZ
+ timeout += (0.5 / HZ);
+ sec = (int)timeout;
+ usec = (int)((timeout - (double)sec) * 1000000);
+#else
+ sec = (int)timeout;
+ usec = (int)((timeout - (double)sec) * 1000000);
+#endif
+ tv.tv_sec = sec;
+ tv.tv_usec = usec;
+ t = &tv;
+ }
+ max_fd = 0;
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&exfds);
+
+ /* call the prepare callback for all handlers */
+ EINA_INLIST_FOREACH(fd_handlers, fdh)
+ if (!fdh->delete_me && fdh->prep_func)
+ {
+ fdh->references++;
+ fdh->prep_func (fdh->prep_data, fdh);
+ fdh->references--;
+ }
+ EINA_INLIST_FOREACH(fd_handlers, fdh)
+ if (!fdh->delete_me)
+ {
+ if (fdh->flags & ECORE_FD_READ)
+ {
+ FD_SET(fdh->fd, &rfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ if (fdh->flags & ECORE_FD_WRITE)
+ {
+ FD_SET(fdh->fd, &wfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ if (fdh->flags & ECORE_FD_ERROR)
+ {
+ FD_SET(fdh->fd, &exfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ }
+ if (_ecore_signal_count_get()) return -1;
+
+ ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
+
+ _ecore_loop_time = ecore_time_get();
+ if (ret < 0)
+ {
+#ifndef _WIN32
+ if (errno == EINTR) return -1;
+ else if (errno == EBADF)
+ _ecore_main_fd_handlers_bads_rem();
+#endif
+ }
+ if (ret > 0)
+ {
+ EINA_INLIST_FOREACH(fd_handlers, fdh)
+ if (!fdh->delete_me)
+ {
+ if (FD_ISSET(fdh->fd, &rfds))
+ fdh->read_active = 1;
+ if (FD_ISSET(fdh->fd, &wfds))
+ fdh->write_active = 1;
+ if (FD_ISSET(fdh->fd, &exfds))
+ fdh->error_active = 1;
+ }
+ _ecore_main_fd_handlers_cleanup();
+#ifdef _WIN32
+ _ecore_main_win32_handlers_cleanup();
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+#ifndef _WIN32
+static void
+_ecore_main_fd_handlers_bads_rem(void)
+{
+ Ecore_Fd_Handler *fdh;
+ Eina_Inlist *l;
+ int found = 0;
+
+ ERR("Removing bad fds");
+ for (l = EINA_INLIST_GET(fd_handlers); l; )
+ {
+ fdh = (Ecore_Fd_Handler *) l;
+ l = l->next;
+ errno = 0;
+
+ if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF))
+ {
+ ERR("Found bad fd at index %d", fdh->fd);
+ if (fdh->flags & ECORE_FD_ERROR)
+ {
+ ERR("Fd set for error! calling user");
+ fdh->references++;
+ if (!fdh->func(fdh->data, fdh))
+ {
+ ERR("Fd function err returned 0, remove it");
+ fdh->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ found++;
+ }
+ fdh->references--;
+ }
+ else
+ {
+ ERR("Problematic fd found at %d! setting it for delete", fdh->fd);
+ fdh->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ found++;
+ }
+ }
+ }
+ if (found == 0)
+ {
+#ifdef HAVE_GLIB
+ ERR("No bad fd found. Maybe a foreign fd from glib?");
+#else
+ ERR("No bad fd found. EEEK!");
+#endif
+ }
+ _ecore_main_fd_handlers_cleanup();
+}
+#endif
+
+static void
+_ecore_main_fd_handlers_cleanup(void)
+{
+ Ecore_Fd_Handler *fdh;
+ Eina_Inlist *l;
+ int deleted_in_use = 0;
+
+ if (!fd_handlers_delete_me) return;
+ for (l = EINA_INLIST_GET(fd_handlers); l; )
+ {
+ fdh = (Ecore_Fd_Handler *) l;
+
+ l = l->next;
+ if (fdh->delete_me)
+ {
+// ERR("Removing fd %d", fdh->fd);
+
+ if (fdh->references)
+ {
+ deleted_in_use++;
+ continue;
+ }
+
+ fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
+ EINA_INLIST_GET(fdh));
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
+ free(fdh);
+ }
+ }
+ if (!deleted_in_use)
+ fd_handlers_delete_me = 0;
+}
+
+#ifdef _WIN32
+static void
+_ecore_main_win32_handlers_cleanup(void)
+{
+ Ecore_Win32_Handler *wh;
+ Eina_Inlist *l;
+ int deleted_in_use = 0;
+
+ if (!win32_handlers_delete_me) return;
+ for (l = EINA_INLIST_GET(win32_handlers); l; )
+ {
+ wh = (Ecore_Win32_Handler *)l;
+
+ l = l->next;
+ if (wh->delete_me)
+ {
+ if (wh->references)
+ {
+ deleted_in_use++;
+ continue;
+ }
+
+ win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
+ EINA_INLIST_GET(wh));
+ ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
+ free(wh);
+ }
+ }
+ if (!deleted_in_use)
+ win32_handlers_delete_me = 0;
+}
+#endif
+
+static void
+_ecore_main_fd_handlers_call(void)
+{
+ if (!fd_handler_current)
+ {
+ /* regular main loop, start from head */
+ fd_handler_current = fd_handlers;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ fd_handler_current = (Ecore_Fd_Handler *)EINA_INLIST_GET(fd_handler_current)->next;
+ }
+
+ while (fd_handler_current)
+ {
+ Ecore_Fd_Handler *fdh = fd_handler_current;
+
+ if (!fdh->delete_me)
+ {
+ if ((fdh->read_active) ||
+ (fdh->write_active) ||
+ (fdh->error_active))
+ {
+ fdh->references++;
+ if (!fdh->func(fdh->data, fdh))
+ {
+ fdh->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ }
+ fdh->references--;
+
+ fdh->read_active = 0;
+ fdh->write_active = 0;
+ fdh->error_active = 0;
+ }
+ }
+
+ if (fd_handler_current) /* may have changed in recursive main loops */
+ fd_handler_current = (Ecore_Fd_Handler *)EINA_INLIST_GET(fd_handler_current)->next;
+ }
+}
+
+static int
+_ecore_main_fd_handlers_buf_call(void)
+{
+ Ecore_Fd_Handler *fdh;
+ int ret;
+
+ ret = 0;
+ EINA_INLIST_FOREACH(fd_handlers, fdh)
+ if (!fdh->delete_me)
+ {
+ if (fdh->buf_func)
+ {
+ fdh->references++;
+ if (fdh->buf_func(fdh->buf_data, fdh))
+ {
+ ret |= fdh->func(fdh->data, fdh);
+ fdh->read_active = 1;
+ }
+ fdh->references--;
+ }
+ }
+
+ return ret;
+}
+
+static void
+_ecore_main_loop_iterate_internal(int once_only)
+{
+ double next_time = -1.0;
+ int have_event = 0;
+ int have_signal;
+
+ in_main_loop++;
+ /* expire any timers */
+ while (_ecore_timer_call(_ecore_loop_time));
+ _ecore_timer_cleanup();
+
+ /* process signals into events .... */
+ while (_ecore_signal_count_get()) _ecore_signal_call();
+ if (_ecore_event_exist())
+ {
+ _ecore_idle_enterer_call();
+ have_event = 1;
+ _ecore_main_select(0.0);
+ _ecore_loop_time = ecore_time_get();
+ _ecore_timer_enable_new();
+ goto process_events;
+ }
+ /* call idle enterers ... */
+ if (!once_only) _ecore_idle_enterer_call();
+ else
+ {
+ have_event = have_signal = 0;
+
+ if (_ecore_main_select(0.0) > 0) have_event = 1;
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+ if (have_signal || have_event)
+ {
+ _ecore_loop_time = ecore_time_get();
+ _ecore_timer_enable_new();
+ goto process_events;
+ }
+ }
+
+ /* if these calls caused any buffered events to appear - deal with them */
+ _ecore_main_fd_handlers_buf_call();
+
+ /* if ther are any - jump to processing them */
+ if (_ecore_event_exist())
+ {
+ have_event = 1;
+ _ecore_main_select(0.0);
+ _ecore_loop_time = ecore_time_get();
+ _ecore_timer_enable_new();
+ goto process_events;
+ }
+ if (once_only)
+ {
+ _ecore_idle_enterer_call();
+ in_main_loop--;
+ _ecore_loop_time = ecore_time_get();
+ _ecore_timer_enable_new();
+ return;
+ }
+
+ if (_ecore_fps_debug)
+ {
+ t2 = ecore_time_get();
+ if ((t1 > 0.0) && (t2 > 0.0))
+ _ecore_fps_debug_runtime_add(t2 - t1);
+ }
+ start_loop:
+ /* any timers re-added as a result of these are allowed to go */
+ _ecore_timer_enable_new();
+ if (do_quit)
+ {
+ _ecore_loop_time = ecore_time_get();
+ in_main_loop--;
+ _ecore_timer_enable_new();
+ return;
+ }
+ if (!_ecore_event_exist())
+ {
+ /* init flags */
+ have_event = have_signal = 0;
+ next_time = _ecore_timer_next_get();
+ /* no timers */
+ if (next_time < 0)
+ {
+ /* no idlers */
+ if (!_ecore_idler_exist())
+ {
+ if (_ecore_main_select(-1.0) > 0) have_event = 1;
+ }
+ /* idlers */
+ else
+ {
+ for (;;)
+ {
+ if (!_ecore_idler_call()) goto start_loop;
+ if (_ecore_event_exist()) break;
+ if (_ecore_main_select(0.0) > 0) have_event = 1;
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+ if (have_event || have_signal) break;
+ if (_ecore_timers_exists()) goto start_loop;
+ if (do_quit) break;
+ }
+ }
+ }
+ /* timers */
+ else
+ {
+ /* no idlers */
+ if (!_ecore_idler_exist())
+ {
+ if (_ecore_main_select(next_time) > 0) have_event = 1;
+ }
+ /* idlers */
+ else
+ {
+ for (;;)
+ {
+ if (!_ecore_idler_call()) goto start_loop;
+ if (_ecore_event_exist()) break;
+ if (_ecore_main_select(0.0) > 0) have_event = 1;
+ if (_ecore_signal_count_get() > 0) have_signal = 1;
+ if (have_event || have_signal) break;
+ next_time = _ecore_timer_next_get();
+ if (next_time <= 0) break;
+ if (do_quit) break;
+ }
+ }
+ }
+ _ecore_loop_time = ecore_time_get();
+ }
+ if (_ecore_fps_debug)
+ {
+ t1 = ecore_time_get();
+ }
+ /* we came out of our "wait state" so idle has exited */
+ if (!once_only)
+ _ecore_idle_exiter_call();
+ /* call the fd handler per fd that became alive... */
+ /* this should read or write any data to the monitored fd and then */
+ /* post events onto the ecore event pipe if necessary */
+ process_events:
+// if (have_event)
+ _ecore_main_fd_handlers_call();
+ _ecore_main_fd_handlers_buf_call();
+// do
+// {
+ /* process signals into events .... */
+ while (_ecore_signal_count_get()) _ecore_signal_call();
+ /* handle events ... */
+ _ecore_event_call();
+ _ecore_main_fd_handlers_cleanup();
+// }
+// while (_ecore_main_fd_handlers_buf_call());
+
+/* ok - too much optimising. let's call idle enterers more often. if we
+ * have events that place more events or jobs etc. on the event queue
+ * we may never get to call an idle enterer
+ if (once_only)
+ */
+ if (once_only)
+ _ecore_idle_enterer_call();
+ in_main_loop--;
+}
+
+#ifdef _WIN32
+static int
+_ecore_main_win32_select(int nfds __UNUSED__, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *tv)
+{
+ HANDLE objects[MAXIMUM_WAIT_OBJECTS];
+ int sockets[MAXIMUM_WAIT_OBJECTS];
+ Ecore_Fd_Handler *fdh;
+ Ecore_Win32_Handler *wh;
+ unsigned int objects_nbr = 0;
+ unsigned int handles_nbr = 0;
+ unsigned int events_nbr = 0;
+ DWORD result;
+ DWORD timeout;
+ MSG msg;
+ unsigned int i;
+ int res;
+
+ /* Create an event object per socket */
+ EINA_INLIST_FOREACH(fd_handlers, fdh)
+ {
+ WSAEVENT event;
+ long network_event;
+
+ network_event = 0;
+ if(FD_ISSET(fdh->fd, readfds))
+ network_event |= FD_READ;
+ if(FD_ISSET(fdh->fd, writefds))
+ network_event |= FD_WRITE;
+ if(FD_ISSET(fdh->fd, exceptfds))
+ network_event |= FD_OOB;
+
+ if(network_event)
+ {
+ event = WSACreateEvent();
+ WSAEventSelect(fdh->fd, event, network_event);
+ objects[objects_nbr] = event;
+ sockets[events_nbr] = fdh->fd;
+ events_nbr++;
+ objects_nbr++;
+ }
+ }
+
+ /* store the HANDLEs in the objects to wait for */
+ EINA_INLIST_FOREACH(win32_handlers, wh)
+ {
+ objects[objects_nbr] = wh->h;
+ handles_nbr++;
+ objects_nbr++;
+ }
+
+ /* Empty the queue before waiting */
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ /* Wait for any message sent or posted to this queue */
+ /* or for one of the passed handles be set to signaled. */
+ if(tv == NULL)
+ timeout = INFINITE;
+ else
+ timeout = (DWORD)(tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0);
+
+ if (timeout == 0) return 0;
+
+ result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE,
+ timeout, QS_ALLINPUT);
+
+ FD_ZERO(readfds);
+ FD_ZERO(writefds);
+ FD_ZERO(exceptfds);
+
+ /* The result tells us the type of event we have. */
+ if (result == WAIT_FAILED)
+ {
+ char *msg;
+
+ msg = evil_last_error_get();
+ ERR(" * %s\n", msg);
+ free(msg);
+ res = -1;
+ }
+ else if (result == WAIT_TIMEOUT)
+ {
+ ERR("time out\n");
+ res = 0;
+ }
+ else if (result == (WAIT_OBJECT_0 + objects_nbr))
+ {
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ res = 0;
+ }
+ else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr))
+ {
+ WSANETWORKEVENTS network_event;
+
+ WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
+
+ if(network_event.lNetworkEvents & FD_READ)
+ FD_SET(sockets[result], readfds);
+ if(network_event.lNetworkEvents & FD_WRITE)
+ FD_SET(sockets[result], writefds);
+ if(network_event.lNetworkEvents & FD_OOB)
+ FD_SET(sockets[result], exceptfds);
+
+ res = 1;
+ }
+ else if ((result >= WAIT_OBJECT_0 + events_nbr) && (result < WAIT_OBJECT_0 + objects_nbr))
+ {
+ if (!win32_handler_current)
+ {
+ /* regular main loop, start from head */
+ win32_handler_current = win32_handlers;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
+ }
+
+ while (win32_handler_current)
+ {
+ wh = win32_handler_current;
+
+ if (objects[result - WAIT_OBJECT_0] == wh->h)
+ if (!wh->delete_me)
+ {
+ wh->references++;
+ if (!wh->func(wh->data, wh))
+ {
+ wh->delete_me = 1;
+ win32_handlers_delete_me = 1;
+ }
+ wh->references--;
+ }
+
+ if (win32_handler_current) /* may have changed in recursive main loops */
+ win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
+ }
+ res = 1;
+ }
+ else
+ {
+ ERR("unknown result...\n");
+ res = -1;
+ }
+
+ /* Remove event objects again */
+ for(i = 0; i < events_nbr; i++)
+ WSACloseEvent(objects[i]);
+
+ return res;
+}
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+/* How of then we should retry to write to the pipe */
+#define ECORE_PIPE_WRITE_RETRY 6
+
+/*
+ * On Windows, pipe() is implemented with sockets.
+ * Contrary to Linux, Windows uses different functions
+ * for sockets and fd's: write() is for fd's and send
+ * is for sockets. So I need to put some win32 code
+ * here. I can't think of a solution where the win32
+ * code is in Evil and not here.
+ */
+
+#ifdef _WIN32
+
+# include <winsock2.h>
+
+# define pipe_write(fd, buffer, size) send((fd), (char *)(buffer), size, 0)
+# define pipe_read(fd, buffer, size) recv((fd), (char *)(buffer), size, 0)
+# define pipe_close(fd) closesocket(fd)
+# define PIPE_FD_INVALID INVALID_SOCKET
+# define PIPE_FD_ERROR SOCKET_ERROR
+
+#else
+
+# include <unistd.h>
+# include <fcntl.h>
+
+# define pipe_write(fd, buffer, size) write((fd), buffer, size)
+# define pipe_read(fd, buffer, size) read((fd), buffer, size)
+# define pipe_close(fd) close(fd)
+# define PIPE_FD_INVALID -1
+# define PIPE_FD_ERROR -1
+
+#endif /* ! _WIN32 */
+
+struct _Ecore_Pipe
+{
+ ECORE_MAGIC;
+ int fd_read;
+ int fd_write;
+ Ecore_Fd_Handler *fd_handler;
+ const void *data;
+ void (*handler) (void *data, void *buffer, unsigned int nbyte);
+ unsigned int len;
+ size_t already_read;
+ void *passed_data;
+};
+
+
+static int _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler);
+
+/**
+ * @defgroup Ecore_Pipe_Group Pipe wrapper
+ *
+ * These functions wrap the pipe / write / read functions to
+ * easily integrate a loop that is in its own thread to the ecore
+ * main loop.
+ *
+ * The ecore_pipe_add() function creates file descriptors (sockets on
+ * Windows) and attach an handle to the ecore main loop. That handle is
+ * called when data is read in the pipe. To write data in the pipe,
+ * just call ecore_pipe_write(). When you are done, just call
+ * ecore_pipe_del().
+ *
+ * Here is an example that uses the pipe wrapper with a Gstreamer
+ * pipeline. For each decoded frame in the Gstreamer thread, a handle
+ * is called in the ecore thread.
+ *
+ * @code#include <gst/gst.h>
+ * #include <Ecore.h>
+ *
+ * static int nbr = 0;
+ *
+ * static GstElement *_buid_pipeline (gchar *filename, Ecore_Pipe *pipe);
+ *
+ * static void new_decoded_pad_cb (GstElement *demuxer,
+ * GstPad *new_pad,
+ * gpointer user_data);
+ *
+ * static void handler(void *data, void *buf, unsigned int len)
+ * {
+ * GstBuffer *buffer = *((GstBuffer **)buf);
+ *
+ * printf ("handler : %p\n", buffer);
+ * printf ("frame : %d %p %lld %p\n", nbr++, data, (long long)GST_BUFFER_DURATION(buffer), buffer);
+ * gst_buffer_unref (buffer);
+ * }
+ *
+ *
+ * static void handoff (GstElement* object,
+ * GstBuffer* arg0,
+ * GstPad* arg1,
+ * gpointer user_data)
+ * {
+ * Ecore_Pipe *pipe;
+ *
+ * pipe = (Ecore_Pipe *)user_data;
+ * printf ("handoff : %p\n", arg0);
+ * gst_buffer_ref (arg0);
+ * ecore_pipe_write(pipe, &arg0, sizeof(arg0));
+ * }
+ *
+ * int
+ * main (int argc, char *argv[])
+ * {
+ * GstElement *pipeline;
+ * char *filename;
+ * Ecore_Pipe *pipe;
+ *
+ * gst_init (&argc, &argv);
+ *
+ * if (!ecore_init ())
+ * {
+ * gst_deinit ();
+ * return 0;
+ * }
+ *
+ * pipe = ecore_pipe_add (handler);
+ * if (!pipe)
+ * {
+ * ecore_shutdown ();
+ * gst_deinit ();
+ * return 0;
+ * }
+ *
+ * if (argc < 2) {
+ * g_print ("usage: %s file.avi\n", argv[0]);
+ * ecore_pipe_del (pipe);
+ * ecore_shutdown ();
+ * gst_deinit ();
+ * return 0;
+ * }
+ * filename = argv[1];
+ *
+ * pipeline = _buid_pipeline (filename, pipe);
+ * if (!pipeline) {
+ * g_print ("Error during the pipeline building\n");
+ * ecore_pipe_del (pipe);
+ * ecore_shutdown ();
+ * gst_deinit ();
+ * return -1;
+ * }
+ *
+ * gst_element_set_state (pipeline, GST_STATE_PLAYING);
+ *
+ * ecore_main_loop_begin();
+ *
+ * ecore_pipe_del (pipe);
+ * ecore_shutdown ();
+ * gst_deinit ();
+ *
+ * return 0;
+ * }
+ *
+ * static void
+ * new_decoded_pad_cb (GstElement *demuxer,
+ * GstPad *new_pad,
+ * gpointer user_data)
+ * {
+ * GstElement *decoder;
+ * GstPad *pad;
+ * GstCaps *caps;
+ * gchar *str;
+ *
+ * caps = gst_pad_get_caps (new_pad);
+ * str = gst_caps_to_string (caps);
+ *
+ * if (g_str_has_prefix (str, "video/")) {
+ * decoder = GST_ELEMENT (user_data);
+ *
+ * pad = gst_element_get_pad (decoder, "sink");
+ * if (GST_PAD_LINK_FAILED (gst_pad_link (new_pad, pad))) {
+ * g_warning ("Failed to link %s:%s to %s:%s", GST_DEBUG_PAD_NAME (new_pad),
+ * GST_DEBUG_PAD_NAME (pad));
+ * }
+ * }
+ * g_free (str);
+ * gst_caps_unref (caps);
+ * }
+ *
+ * static GstElement *
+ * _buid_pipeline (gchar *filename, Ecore_Pipe *pipe)
+ * {
+ * GstElement *pipeline;
+ * GstElement *filesrc;
+ * GstElement *demuxer;
+ * GstElement *decoder;
+ * GstElement *sink;
+ GstStateChangeReturn res;
+ *
+ * pipeline = gst_pipeline_new ("pipeline");
+ * if (!pipeline)
+ * return NULL;
+ *
+ * filesrc = gst_element_factory_make ("filesrc", "filesrc");
+ * if (!filesrc) {
+ * printf ("no filesrc");
+ * goto failure;
+ * }
+ * g_object_set (G_OBJECT (filesrc), "location", filename, NULL);
+ *
+ * demuxer = gst_element_factory_make ("oggdemux", "demuxer");
+ * if (!demuxer) {
+ * printf ("no demux");
+ * goto failure;
+ * }
+ *
+ * decoder = gst_element_factory_make ("theoradec", "decoder");
+ * if (!decoder) {
+ * printf ("no dec");
+ * goto failure;
+ * }
+ *
+ * g_signal_connect (demuxer, "pad-added",
+ * G_CALLBACK (new_decoded_pad_cb), decoder);
+ *
+ * sink = gst_element_factory_make ("fakesink", "sink");
+ * if (!sink) {
+ * printf ("no sink");
+ * goto failure;
+ * }
+ * g_object_set (G_OBJECT (sink), "sync", EINA_TRUE, NULL);
+ * g_object_set (G_OBJECT (sink), "signal-handoffs", EINA_TRUE, NULL);
+ * g_signal_connect (sink, "handoff",
+ * G_CALLBACK (handoff), pipe);
+ *
+ * gst_bin_add_many (GST_BIN (pipeline),
+ * filesrc, demuxer, decoder, sink, NULL);
+ *
+ * if (!gst_element_link (filesrc, demuxer))
+ * goto failure;
+ * if (!gst_element_link (decoder, sink))
+ * goto failure;
+ *
+ * res = gst_element_set_state (pipeline, GST_STATE_PAUSED);
+ * if (res == GST_STATE_CHANGE_FAILURE)
+ * goto failure;
+ *
+ * res = gst_element_get_state( pipeline, NULL, NULL, GST_CLOCK_TIME_NONE );
+ * if (res != GST_STATE_CHANGE_SUCCESS)
+ * goto failure;
+ *
+ * return pipeline;
+ *
+ * failure:
+ * gst_object_unref (GST_OBJECT (pipeline));
+ * return NULL;
+ * }
+ * @endcode
+ */
+
+
+/**
+ * Create two file descriptors (sockets on Windows). Add
+ * a callback that will be called when the file descriptor that
+ * is listened receives data. An event is also put in the event
+ * queue when data is received.
+ *
+ * @param handler The handler called when data is received.
+ * @param data Data to pass to @p handler when it is called.
+ * @return A newly created Ecore_Pipe object if successful.
+ * @c NULL otherwise.
+ * @ingroup Ecore_Pipe_Group
+ */
+EAPI Ecore_Pipe *
+ecore_pipe_add(void (*handler) (void *data, void *buffer, unsigned int nbyte),
+ const void *data)
+{
+ Ecore_Pipe *p;
+ int fds[2];
+
+ if (!handler) return NULL;
+
+ p = (Ecore_Pipe *)calloc(1, sizeof(Ecore_Pipe));
+ if (!p) return NULL;
+
+ if (pipe(fds))
+ {
+ free(p);
+ return NULL;
+ }
+
+ ECORE_MAGIC_SET(p, ECORE_MAGIC_PIPE);
+ p->fd_read = fds[0];
+ p->fd_write = fds[1];
+ p->handler = handler;
+ p->data = data;
+
+ fcntl(p->fd_read, F_SETFL, O_NONBLOCK);
+ p->fd_handler = ecore_main_fd_handler_add(p->fd_read,
+ ECORE_FD_READ,
+ _ecore_pipe_read,
+ p,
+ NULL, NULL);
+ return p;
+}
+
+/**
+ * Free an Ecore_Pipe object created with ecore_pipe_add().
+ *
+ * @param p The Ecore_Pipe object to be freed.
+ * @return The pointer to the private data
+ * @ingroup Ecore_Pipe_Group
+ */
+EAPI void *
+ecore_pipe_del(Ecore_Pipe *p)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
+ {
+ ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del");
+ return NULL;
+ }
+ if (p->fd_handler != NULL) ecore_main_fd_handler_del(p->fd_handler);
+ if (p->fd_read != PIPE_FD_INVALID) pipe_close(p->fd_read);
+ if (p->fd_write != PIPE_FD_INVALID) pipe_close(p->fd_write);
+ data = (void *)p->data;
+ free(p);
+ return data;
+}
+
+/**
+ * Close the read end of an Ecore_Pipe object created with ecore_pipe_add().
+ *
+ * @param p The Ecore_Pipe object.
+ * @ingroup Ecore_Pipe_Group
+ */
+EAPI void
+ecore_pipe_read_close(Ecore_Pipe *p)
+{
+ if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
+ {
+ ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close");
+ return;
+ }
+ ecore_main_fd_handler_del(p->fd_handler);
+ p->fd_handler = NULL;
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+}
+
+/**
+ * Close the write end of an Ecore_Pipe object created with ecore_pipe_add().
+ *
+ * @param p The Ecore_Pipe object.
+ * @ingroup Ecore_Pipe_Group
+ */
+EAPI void
+ecore_pipe_write_close(Ecore_Pipe *p)
+{
+ if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
+ {
+ ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close");
+ return;
+ }
+ pipe_close(p->fd_write);
+ p->fd_write = PIPE_FD_INVALID;
+}
+
+/**
+ * Write on the file descriptor the data passed as parameter.
+ *
+ * @param p The Ecore_Pipe object.
+ * @param buffer The data to write into the pipe.
+ * @param nbytes The size of the @p buffer in bytes
+ * @return Returns EINA_TRUE on a successful write, EINA_FALSE on an error
+ * @ingroup Ecore_Pipe_Group
+ */
+EAPI int
+ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes)
+{
+ ssize_t ret;
+ size_t already_written = 0;
+ int retry = ECORE_PIPE_WRITE_RETRY;
+
+ if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
+ {
+ ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write");
+ return EINA_FALSE;
+ }
+
+ if (p->fd_write == PIPE_FD_INVALID) return EINA_FALSE;
+
+ /* First write the len into the pipe */
+ do
+ {
+ ret = pipe_write(p->fd_write, &nbytes, sizeof(nbytes));
+ if (ret == sizeof(nbytes))
+ {
+ retry = ECORE_PIPE_WRITE_RETRY;
+ break;
+ }
+ else if (ret > 0)
+ {
+ /* XXX What should we do here? */
+ ERR("The length of the data was not written complete"
+ " to the pipe");
+ return EINA_FALSE;
+ }
+ else if (ret == PIPE_FD_ERROR && errno == EPIPE)
+ {
+ pipe_close(p->fd_write);
+ p->fd_write = PIPE_FD_INVALID;
+ return EINA_FALSE;
+ }
+ else if (ret == PIPE_FD_ERROR && errno == EINTR)
+ /* try it again */
+ ;
+ else
+ {
+ ERR("An unhandled error (ret: %zd errno: %d)"
+ "occured while writing to the pipe the length",
+ ret, errno);
+ }
+ }
+ while (retry--);
+
+ if (retry != ECORE_PIPE_WRITE_RETRY) return EINA_FALSE;
+
+ /* and now pass the data to the pipe */
+ do
+ {
+ ret = pipe_write(p->fd_write,
+ ((unsigned char *)buffer) + already_written,
+ nbytes - already_written);
+
+ if (ret == (ssize_t)(nbytes - already_written))
+ return EINA_TRUE;
+ else if (ret >= 0)
+ {
+ already_written -= ret;
+ continue;
+ }
+ else if (ret == PIPE_FD_ERROR && errno == EPIPE)
+ {
+ pipe_close(p->fd_write);
+ p->fd_write = PIPE_FD_INVALID;
+ return EINA_FALSE;
+ }
+ else if (ret == PIPE_FD_ERROR && errno == EINTR)
+ /* try it again */
+ ;
+ else
+ {
+ ERR("An unhandled error (ret: %zd errno: %d)"
+ "occured while writing to the pipe the length",
+ ret, errno);
+ }
+ }
+ while (retry--);
+
+ return EINA_FALSE;
+}
+
+/* Private function */
+
+static int
+_ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Ecore_Pipe *p;
+ double start_time;
+
+ p = (Ecore_Pipe *)data;
+ start_time = ecore_time_get();
+
+ do
+ {
+ ssize_t ret;
+
+ /* if we already have read some data we don't need to read the len
+ * but to finish the already started job
+ */
+ if (p->len == 0)
+ {
+ /* read the len of the passed data */
+ ret = pipe_read(p->fd_read, &p->len, sizeof(p->len));
+
+ /* catch the non error case first */
+ if (ret == sizeof(p->len))
+ ;
+ else if (ret > 0)
+ {
+ /* XXX What should we do here? */
+ ERR("Only read %zd bytes from the pipe, although"
+ " we need to read %zd bytes.", ret, sizeof(p->len));
+ }
+ else if (ret == 0)
+ {
+ p->handler((void *)p->data, NULL, 0);
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ p->fd_handler = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+#ifndef _WIN32
+ else if ((ret == PIPE_FD_ERROR) && ((errno == EINTR) || (errno == EAGAIN)))
+ return ECORE_CALLBACK_RENEW;
+ else
+ {
+ ERR("An unhandled error (ret: %zd errno: %d)"
+ "occured while reading from the pipe the length",
+ ret, errno);
+ return ECORE_CALLBACK_RENEW;
+ }
+#else
+ else /* ret == PIPE_FD_ERROR is the only other case on Windows */
+ {
+ if (WSAGetLastError() != WSAEWOULDBLOCK)
+ {
+ p->handler((void *)p->data, NULL, 0);
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ p->fd_handler = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+ }
+#endif
+ }
+
+ if (!p->passed_data)
+ p->passed_data = malloc(p->len);
+
+ /* and read the passed data */
+ ret = pipe_read(p->fd_read,
+ ((unsigned char *)p->passed_data) + p->already_read,
+ p->len - p->already_read);
+
+ /* catch the non error case first */
+ if (ret == (ssize_t)(p->len - p->already_read))
+ {
+ p->handler((void *)p->data, p->passed_data, p->len);
+ free(p->passed_data);
+ /* reset all values to 0 */
+ p->passed_data = NULL;
+ p->already_read = 0;
+ p->len = 0;
+ }
+ else if (ret >= 0)
+ {
+ p->already_read += ret;
+ return ECORE_CALLBACK_RENEW;
+ }
+ else if (ret == 0)
+ {
+ p->handler((void *)p->data, NULL, 0);
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ p->fd_handler = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+#ifndef _WIN32
+ else if (ret == PIPE_FD_ERROR && (errno == EINTR || errno == EAGAIN))
+ return ECORE_CALLBACK_RENEW;
+ else
+ {
+ ERR("An unhandled error (ret: %zd errno: %d)"
+ "occured while reading from the pipe the data",
+ ret, errno);
+ return ECORE_CALLBACK_RENEW;
+ }
+#else
+ else /* ret == PIPE_FD_ERROR is the only other case on Windows */
+ {
+ if (WSAGetLastError() != WSAEWOULDBLOCK)
+ {
+ p->handler((void *)p->data, NULL, 0);
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ p->fd_handler = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+ else
+ break;
+ }
+#endif
+ }
+ while (ecore_time_get() - start_time < ecore_animator_frametime_get());
+
+ return ECORE_CALLBACK_RENEW;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Poller
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ int ibit;
+ unsigned char delete_me : 1;
+ int (*func) (void *data);
+ void *data;
+};
+
+
+static Ecore_Timer *timer = NULL;
+static int min_interval = -1;
+static int interval_incr = 0;
+static int at_tick = 0;
+static int just_added_poller = 0;
+static int poller_delete_count = 0;
+static int poller_walking = 0;
+static double poll_interval = 0.125;
+static double poll_cur_interval = 0.0;
+static double last_tick = 0.0;
+static Ecore_Poller *pollers[16] =
+{
+ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+};
+static unsigned short poller_counters[16] =
+{
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0
+};
+
+static void _ecore_poller_next_tick_eval(void);
+static int _ecore_poller_cb_timer(void *data);
+
+static void
+_ecore_poller_next_tick_eval(void)
+{
+ int i;
+ double interval;
+
+ min_interval = -1;
+ for (i = 0; i < 15; i++)
+ {
+ if (pollers[i])
+ {
+ min_interval = i;
+ break;
+ }
+ }
+ if (min_interval < 0)
+ {
+ /* no pollers */
+ if (timer)
+ {
+ ecore_timer_del(timer);
+ timer = NULL;
+ }
+ return;
+ }
+ interval_incr = (1 << min_interval);
+ interval = interval_incr * poll_interval;
+ /* we are at the tick callback - so no need to do inter-tick adjustments
+ * so we can fasttrack this as t -= last_tick in theory is 0.0 (though
+ * in practice it will be a very very very small value. also the tick
+ * callback will adjust the timer interval at the end anyway */
+ if (at_tick)
+ {
+ if (!timer)
+ timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL);
+ }
+ else
+ {
+ double t;
+
+ if (!timer)
+ timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL);
+ else
+ {
+ t = ecore_time_get();
+ if (interval != poll_cur_interval)
+ {
+ t -= last_tick; /* time since we last ticked */
+ /* delete the timer and reset it to tick off in the new
+ * time interval. at the tick this will be adjusted */
+ ecore_timer_del(timer);
+ timer = ecore_timer_add(interval - t,
+ _ecore_poller_cb_timer, NULL);
+ }
+ }
+ }
+ poll_cur_interval = interval;
+}
+
+static int
+_ecore_poller_cb_timer(void *data __UNUSED__)
+{
+ int i;
+ Ecore_Poller *poller, *l;
+ int changes = 0;
+
+ at_tick++;
+ last_tick = ecore_time_get();
+ /* we have 16 counters - each incriments every time the poller counter
+ * "ticks". it incriments by the minimum interval (which can be 1, 2, 4,
+ * 7, 16 etc. up to 32768) */
+ for (i = 0; i < 15; i++)
+ {
+ poller_counters[i] += interval_incr;
+ /* wrap back to 0 if we exceed out loop count for the counter */
+ if (poller_counters[i] >= (1 << i)) poller_counters[i] = 0;
+ }
+
+ just_added_poller = 0;
+ /* walk the pollers now */
+ poller_walking++;
+ for (i = 0; i < 15; i++)
+ {
+ /* if the counter is @ 0 - this means that counter "went off" this
+ * tick interval, so run all pollers hooked to that counter */
+ if (poller_counters[i] == 0)
+ {
+ EINA_INLIST_FOREACH(pollers[i], poller)
+ {
+ if (!poller->delete_me)
+ {
+ if (!poller->func(poller->data))
+ {
+ if (!poller->delete_me)
+ {
+ poller->delete_me = 1;
+ poller_delete_count++;
+ }
+ }
+ }
+ }
+ }
+ }
+ poller_walking--;
+
+ /* handle deletes afterwards */
+ if (poller_delete_count > 0)
+ {
+ /* FIXME: walk all pollers and remove deleted ones */
+ for (i = 0; i < 15; i++)
+ {
+ for (l = pollers[i]; l;)
+ {
+ poller = l;
+ l = (Ecore_Poller *) EINA_INLIST_GET(l)->next;
+ if (poller->delete_me)
+ {
+ pollers[i] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller));
+ free(poller);
+ poller_delete_count--;
+ changes++;
+ if (poller_delete_count <= 0) break;
+ }
+ }
+ if (poller_delete_count <= 0) break;
+ }
+ }
+ /* if we deleted or added any pollers, then we need to re-evaluate our
+ * minimum poll interval */
+ if ((changes > 0) || (just_added_poller > 0))
+ _ecore_poller_next_tick_eval();
+
+ just_added_poller = 0;
+ poller_delete_count = 0;
+
+ at_tick--;
+
+ /* if the timer was deleted then there is no point returning 1 - ambiguous
+ * if we do as it im plies "keep running me" but we have been deleted
+ * anyway */
+ if (!timer) return 0;
+
+ /* adjust interval */
+ ecore_timer_interval_set(timer, poll_cur_interval);
+ return 1;
+}
+
+/**
+ * @defgroup Ecore_Poll_Group Ecore Poll Functions
+ *
+ * These functions are for the need to poll information, but provide a shared
+ * abstracted API to pool such polling to minimise wakeup and ensure all the
+ * polling happens in as few spots as possible areound a core poll interval.
+ * For now only 1 core poller type is supprted: ECORE_POLLER_CORE
+ */
+
+
+/**
+ * Sets the time between ticks (in seconds) for the given ticker clock.
+ * @param type The ticker type to adjust
+ * @param poll_time The time (in seconds) between ticks of the clock
+ * @ingroup Ecore_Poller_Group
+ *
+ * This will adjust the time between ticks of the given ticker type defined
+ * by @p type to the time period defined by @p poll_time.
+ */
+EAPI void
+ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__, double poll_time)
+{
+ poll_interval = poll_time;
+ _ecore_poller_next_tick_eval();
+}
+
+/**
+ * Gets the time between ticks (in seconds) for the given ticker clock.
+ * @param type The ticker type to query
+ * @return The time in seconds between ticks of the ticker clock
+ * @ingroup Ecore_Poller_Group
+ *
+ * This will get the time between ticks of the specifider ticker clock.
+ */
+EAPI double
+ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__)
+{
+ return poll_interval;
+}
+
+/**
+ * Creates a poller to call the given function at a particular tick interval.
+ * @param type The ticker type to attach the poller to
+ * @param interval The poll interval
+ * @param func The given function. If @p func returns 1, the poller is
+ * rescheduled for the next tick interval.
+ * @param data Data to pass to @p func when it is called.
+ * @return A poller object on success. @c NULL on failure.
+ * @ingroup Ecore_Poller_Group
+ *
+ * This function adds a poller callback that is to be called regularly
+ * along with all other poller callbacks so the pollers are synchronized with
+ * all other pollers running off the same poller type and at the same tick
+ * interval. This should be used for polling things when polling is desired
+ * or required, and you do not have specific requirements on the exact times
+ * to poll and want to avoid extra process wakeups for polling. This will
+ * save power as the CPU has more of a chance to go into a low power state
+ * the longer it is asleep for, so this should be used if you are at all
+ * power conscious.
+ *
+ * The @p type parameter defines the poller tick type (there is a virtual
+ * clock ticking all the time - though ecore avoids making it tick when
+ * there will not be any work to do at that tick point). There is only one
+ * ticker at the moment - that is ECORE_POLLER_CORE. This is here for future
+ * expansion if multiple clocks with different frequencies are really required.
+ * The default time between ticks for the ECORE_POLLER_CORE ticker is 0.125
+ * seconds.
+ *
+ * The @p interval is the number of ticker ticks that will pass by in between
+ * invocations of the @p func callback. This must be between 1 and 32768
+ * inclusive, and must be a power of 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768).
+ * If it is 1, then the function will be called every tick. if it is 2, then it
+ * will be called every 2nd tick, if it is 8, then every 8th tick etc. Exactly
+ * which tick is undefined, as only the interval between calls can be defined.
+ * Ecore will endeavour to keep pollers synchronised and to call as many in
+ * 1 wakeup event as possible.
+ *
+ * This function adds a poller and returns its handle on success and NULL on
+ * failure. The function @p func will be called at tick intervals described
+ * above. The function will be passed the @p data pointer as its parameter.
+ *
+ * When the poller @p func is called, it must return a value of either
+ * 1 (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL). If it
+ * returns 1, it will be called again at the next tick, or if it returns
+ * 0 it will be deleted automatically making any references/handles for it
+ * invalid.
+ */
+EAPI Ecore_Poller *
+ecore_poller_add(Ecore_Poller_Type type __UNUSED__, int interval, int (*func) (void *data), const void *data)
+{
+ Ecore_Poller *poller;
+ int ibit;
+
+ if (!func) return NULL;
+ if (interval < 1) interval = 1;
+
+ poller = calloc(1, sizeof(Ecore_Poller));
+ if (!poller) return NULL;
+ ECORE_MAGIC_SET(poller, ECORE_MAGIC_POLLER);
+ /* interval MUST be a power of 2, so enforce it */
+ if (interval < 1) interval = 1;
+ ibit = -1;
+ while (interval != 0)
+ {
+ ibit++;
+ interval >>= 1;
+ }
+ /* only allow up to 32768 - i.e. ibit == 15, so limit it */
+ if (ibit > 15) ibit = 15;
+
+ poller->ibit = ibit;
+ poller->func = func;
+ poller->data = (void *)data;
+ pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ if (poller_walking)
+ just_added_poller++;
+ else
+ _ecore_poller_next_tick_eval();
+ return poller;
+}
+
+/**
+ * Delete the specified poller from the timer list.
+ * @param poller The poller to delete.
+ * @return The data pointer set for the timer when @ref ecore_poller_add was
+ * called. @c NULL is returned if the function is unsuccessful.
+ * @ingroup Ecore_Poller_Group
+ *
+ * Note: @p poller must be a valid handle. If the poller function has already
+ * returned 0, the handle is no longer valid (and does not need to be delete).
+ */
+EAPI void *
+ecore_poller_del(Ecore_Poller *poller)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
+ {
+ ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
+ "ecore_poller_del");
+ return NULL;
+ }
+ /* we are walking the poller list - a bad idea to remove from it while
+ * walking it, so just flag it as delete_me and come back to it after
+ * the loop has finished */
+ if (poller_walking > 0)
+ {
+ poller_delete_count++;
+ poller->delete_me = 1;
+ return poller->data;
+ }
+ /* not in loop so safe - delete immediately */
+ data = poller->data;
+ pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ free(poller);
+ _ecore_poller_next_tick_eval();
+ return data;
+}
+
+void
+_ecore_poller_shutdown(void)
+{
+ int i;
+ Ecore_Poller *poller;
+
+ for (i = 0; i < 15; i++)
+ {
+ while ((poller = pollers[i]))
+ {
+ pollers[i] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i]));
+ free(poller);
+ }
+ }
+}
--- /dev/null
+#ifndef _ECORE_PRIVATE_H
+#define _ECORE_PRIVATE_H
+
+extern int _ecore_log_dom ;
+#ifdef _ECORE_DEFAULT_LOG_DOM
+# undef _ECORE_DEFAULT_LOG_DOM
+#endif
+#define _ECORE_DEFAULT_LOG_DOM _ecore_log_dom
+
+#ifdef ECORE_DEFAULT_LOG_COLOR
+# undef ECORE_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ECORE_DEFAULT_LOG_DOM, __VA_ARGS__)
+
+#ifndef PATH_MAX
+# define PATH_MAX 4096
+#endif
+
+#ifndef MIN
+# define MIN(x, y) (((x) > (y)) ? (y) : (x))
+#endif
+
+#ifndef MAX
+# define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#endif
+
+#ifndef ABS
+# define ABS(x) ((x) < 0 ? -(x) : (x))
+#endif
+
+#ifndef CLAMP
+# define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
+#endif
+
+#define READBUFSIZ 65536
+
+#define ECORE_MAGIC_NONE 0x1234fedc
+#define ECORE_MAGIC_EXE 0xf7e812f5
+#define ECORE_MAGIC_TIMER 0xf7d713f4
+#define ECORE_MAGIC_IDLER 0xf7c614f3
+#define ECORE_MAGIC_IDLE_ENTERER 0xf7b515f2
+#define ECORE_MAGIC_IDLE_EXITER 0xf7601afd
+#define ECORE_MAGIC_FD_HANDLER 0xf7a416f1
+#define ECORE_MAGIC_EVENT_HANDLER 0xf79317f0
+#define ECORE_MAGIC_EVENT_FILTER 0xf78218ff
+#define ECORE_MAGIC_EVENT 0xf77119fe
+#define ECORE_MAGIC_ANIMATOR 0xf7643ea5
+#define ECORE_MAGIC_POLLER 0xf7568127
+#define ECORE_MAGIC_PIPE 0xf7458226
+#define ECORE_MAGIC_WIN32_HANDLER 0xf7e8f1a3
+#define ECORE_MAGIC_JOB 0x76543210
+
+
+#define ECORE_MAGIC Ecore_Magic __magic
+
+#define ECORE_MAGIC_SET(d, m) (d)->__magic = (m)
+#define ECORE_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
+#define ECORE_MAGIC_FAIL(d, m, fn) _ecore_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn));
+
+/* undef the following, we want our version */
+#undef FREE
+#define FREE(ptr) free(ptr); ptr = NULL;
+
+#undef IF_FREE
+#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
+
+#undef IF_FN_DEL
+#define IF_FN_DEL(_fn, ptr) if (ptr) { _fn(ptr); ptr = NULL; }
+
+EAPI void ecore_print_warning(const char *function, const char *sparam);
+
+/* convenience macros for checking pointer parameters for non-NULL */
+#undef CHECK_PARAM_POINTER_RETURN
+#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
+ if (!(param)) \
+ { \
+ ecore_print_warning(__FUNCTION__, sparam); \
+ return ret; \
+ }
+
+#undef CHECK_PARAM_POINTER
+#define CHECK_PARAM_POINTER(sparam, param) \
+ if (!(param)) \
+ { \
+ ecore_print_warning(__FUNCTION__, sparam); \
+ return; \
+ }
+
+typedef unsigned int Ecore_Magic;
+
+EAPI void _ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname);
+
+void _ecore_timer_shutdown(void);
+void _ecore_timer_cleanup(void);
+void _ecore_timer_enable_new(void);
+double _ecore_timer_next_get(void);
+int _ecore_timers_exists(void);
+int _ecore_timer_call(double when);
+
+void _ecore_idler_shutdown(void);
+int _ecore_idler_call(void);
+int _ecore_idler_exist(void);
+
+void _ecore_idle_enterer_shutdown(void);
+void _ecore_idle_enterer_call(void);
+int _ecore_idle_enterer_exist(void);
+
+void _ecore_idle_exiter_shutdown(void);
+void _ecore_idle_exiter_call(void);
+int _ecore_idle_exiter_exist(void);
+
+void _ecore_event_shutdown(void);
+int _ecore_event_exist(void);
+Ecore_Event *_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data);
+void _ecore_event_call(void);
+
+Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe);
+void _ecore_exe_doomsday_clock_set(Ecore_Exe *exe, Ecore_Timer *dc);
+
+EAPI void *_ecore_event_signal_user_new(void);
+void *_ecore_event_signal_hup_new(void);
+void *_ecore_event_signal_exit_new(void);
+void *_ecore_event_signal_power_new(void);
+void *_ecore_event_signal_realtime_new(void);
+
+void _ecore_main_shutdown(void);
+
+#ifdef _WIN32
+static inline void _ecore_signal_shutdown(void) { }
+static inline void _ecore_signal_init(void) { }
+static inline int _ecore_signal_count_get(void) { return 0; }
+static inline void _ecore_signal_call(void) { }
+#else
+void _ecore_signal_shutdown(void);
+void _ecore_signal_init(void);
+int _ecore_signal_count_get(void);
+void _ecore_signal_call(void);
+#endif
+
+void _ecore_exe_init(void);
+void _ecore_exe_shutdown(void);
+#ifndef _WIN32
+Ecore_Exe *_ecore_exe_find(pid_t pid);
+void *_ecore_exe_event_del_new(void);
+void _ecore_exe_event_del_free(void *data, void *ev);
+#endif
+
+void _ecore_animator_shutdown(void);
+
+void _ecore_poller_shutdown(void);
+
+EAPI void *_ecore_list2_append (void *in_list, void *in_item);
+EAPI void *_ecore_list2_prepend (void *in_list, void *in_item);
+EAPI void *_ecore_list2_append_relative (void *in_list, void *in_item, void *in_relative);
+EAPI void *_ecore_list2_prepend_relative (void *in_list, void *in_item, void *in_relative);
+EAPI void *_ecore_list2_remove (void *in_list, void *in_item);
+EAPI void *_ecore_list2_find (void *in_list, void *in_item);
+
+void _ecore_fps_debug_init(void);
+void _ecore_fps_debug_shutdown(void);
+void _ecore_fps_debug_runtime_add(double t);
+
+void _ecore_thread_init(void);
+void _ecore_thread_shutdown(void);
+
+void _ecore_glib_init(void);
+void _ecore_glib_shutdown(void);
+
+void _ecore_job_init(void);
+void _ecore_job_shutdown(void);
+
+extern int _ecore_fps_debug;
+extern double _ecore_loop_time;
+extern Eina_Bool _ecore_glib_always_integrate;
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+/* make mono happy - this is evil though... */
+#undef SIGPWR
+/* valgrind in some versions/setups uses SIGRT's... hmmm */
+#undef SIGRTMIN
+
+typedef void (*Signal_Handler)(int sig, siginfo_t *si, void *foo);
+
+static void _ecore_signal_callback_set(int sig, Signal_Handler func);
+static void _ecore_signal_callback_ignore(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigchld(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigusr1(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigusr2(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sighup(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigquit(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigint(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigterm(int sig, siginfo_t *si, void *foo);
+#ifdef SIGPWR
+static void _ecore_signal_callback_sigpwr(int sig, siginfo_t *si, void *foo);
+#endif
+
+#ifdef SIGRTMIN
+static void _ecore_signal_callback_sigrt(int sig, siginfo_t *si, void *foo);
+#endif
+
+static int _ecore_signal_exe_exit_delay(void *data);
+
+//#define MAXSIGQ 256 // 32k
+#define MAXSIGQ 64 // 8k
+
+static volatile sig_atomic_t sig_count = 0;
+static volatile sig_atomic_t sigchld_count = 0;
+static volatile sig_atomic_t sigusr1_count = 0;
+static volatile sig_atomic_t sigusr2_count = 0;
+static volatile sig_atomic_t sighup_count = 0;
+static volatile sig_atomic_t sigquit_count = 0;
+static volatile sig_atomic_t sigint_count = 0;
+static volatile sig_atomic_t sigterm_count = 0;
+#ifdef SIGPWR
+static volatile sig_atomic_t sigpwr_count = 0;
+#endif
+#ifdef SIGRTMIN
+static volatile sig_atomic_t *sigrt_count = NULL;
+#endif
+
+static volatile siginfo_t sigchld_info[MAXSIGQ];
+static volatile siginfo_t sigusr1_info[MAXSIGQ];
+static volatile siginfo_t sigusr2_info[MAXSIGQ];
+static volatile siginfo_t sighup_info[MAXSIGQ];
+static volatile siginfo_t sigquit_info[MAXSIGQ];
+static volatile siginfo_t sigint_info[MAXSIGQ];
+static volatile siginfo_t sigterm_info[MAXSIGQ];
+#ifdef SIGPWR
+static volatile siginfo_t sigpwr_info[MAXSIGQ];
+#endif
+#ifdef SIGRTMIN
+static volatile siginfo_t *sigrt_info[MAXSIGQ];
+#endif
+
+void
+_ecore_signal_shutdown(void)
+{
+#ifdef SIGRTMIN
+ int i, num = SIGRTMAX - SIGRTMIN;
+#endif
+
+ _ecore_signal_callback_set(SIGPIPE, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGALRM, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGCHLD, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGUSR1, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGUSR2, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGHUP, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGQUIT, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGINT, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGTERM, (Signal_Handler) SIG_DFL);
+#ifdef SIGPWR
+ _ecore_signal_callback_set(SIGPWR, (Signal_Handler) SIG_DFL);
+ sigpwr_count = 0;
+#endif
+ sigchld_count = 0;
+ sigusr1_count = 0;
+ sigusr2_count = 0;
+ sighup_count = 0;
+ sigquit_count = 0;
+ sigint_count = 0;
+ sigterm_count = 0;
+ sig_count = 0;
+
+#ifdef SIGRTMIN
+ for (i = 0; i < num; i++)
+ {
+ _ecore_signal_callback_set(SIGRTMIN + i, (Signal_Handler) SIG_DFL);
+ sigrt_count[i] = 0;
+ }
+
+ if (sigrt_count)
+ {
+ free((sig_atomic_t *) sigrt_count);
+ sigrt_count = NULL;
+ }
+
+ for (i = 0; i < MAXSIGQ; i++)
+ {
+ if (sigrt_info[i])
+ {
+ free((siginfo_t *) sigrt_info[i]);
+ sigrt_info[i] = NULL;
+ }
+ }
+#endif
+}
+
+void
+_ecore_signal_init(void)
+{
+#ifdef SIGRTMIN
+ int i, num = SIGRTMAX - SIGRTMIN;
+#endif
+
+ _ecore_signal_callback_set(SIGPIPE, _ecore_signal_callback_ignore);
+ _ecore_signal_callback_set(SIGALRM, _ecore_signal_callback_ignore);
+ _ecore_signal_callback_set(SIGCHLD, _ecore_signal_callback_sigchld);
+ _ecore_signal_callback_set(SIGUSR1, _ecore_signal_callback_sigusr1);
+ _ecore_signal_callback_set(SIGUSR2, _ecore_signal_callback_sigusr2);
+ _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup);
+ _ecore_signal_callback_set(SIGQUIT, _ecore_signal_callback_sigquit);
+ _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint);
+ _ecore_signal_callback_set(SIGTERM, _ecore_signal_callback_sigterm);
+#ifdef SIGPWR
+ _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr);
+#endif
+
+#ifdef SIGRTMIN
+ sigrt_count = calloc(1, sizeof(sig_atomic_t) * num);
+ assert(sigrt_count);
+
+ for (i = 0; i < MAXSIGQ; i++)
+ {
+ sigrt_info[i] = calloc(1, sizeof(siginfo_t) * num);
+ assert(sigrt_info[i]);
+ }
+
+ for (i = 0; i < num; i++)
+ _ecore_signal_callback_set(SIGRTMIN + i, _ecore_signal_callback_sigrt);
+#endif
+}
+
+int
+_ecore_signal_count_get(void)
+{
+ return sig_count;
+}
+
+void
+_ecore_signal_call(void)
+{
+#ifdef SIGRTMIN
+ int i, num = SIGRTMAX - SIGRTMIN;
+#endif
+ volatile sig_atomic_t n;
+ sigset_t oldset, newset;
+
+ if (sig_count == 0) return;
+ sigemptyset(&newset);
+ sigaddset(&newset, SIGPIPE);
+ sigaddset(&newset, SIGALRM);
+ sigaddset(&newset, SIGCHLD);
+ sigaddset(&newset, SIGUSR1);
+ sigaddset(&newset, SIGUSR2);
+ sigaddset(&newset, SIGHUP);
+ sigaddset(&newset, SIGQUIT);
+ sigaddset(&newset, SIGINT);
+ sigaddset(&newset, SIGTERM);
+#ifdef SIGPWR
+ sigaddset(&newset, SIGPWR);
+#endif
+#ifdef SIGRTMIN
+ for (i = 0; i < num; i++)
+ sigaddset(&newset, SIGRTMIN + i);
+#endif
+ sigprocmask(SIG_BLOCK, &newset, &oldset);
+ if (sigchld_count > MAXSIGQ)
+ WRN("%i SIGCHLD in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sigchld_count, MAXSIGQ);
+ for (n = 0; n < sigchld_count; n++)
+ {
+ pid_t pid;
+ int status;
+
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+ {
+ Ecore_Exe_Event_Del *e;
+
+ /* FIXME: If this process is set respawn, respawn with a suitable backoff
+ * period for those that need too much respawning.
+ */
+ e = _ecore_exe_event_del_new();
+ if (e)
+ {
+ if (WIFEXITED(status))
+ {
+ e->exit_code = WEXITSTATUS(status);
+ e->exited = 1;
+ }
+ else if (WIFSIGNALED(status))
+ {
+ e->exit_signal = WTERMSIG(status);
+ e->signalled = 1;
+ }
+ e->pid = pid;
+ e->exe = _ecore_exe_find(pid);
+
+ if ((n < MAXSIGQ) && (sigchld_info[n].si_signo))
+ e->data = sigchld_info[n]; /* No need to clone this. */
+
+ if ((e->exe) && (ecore_exe_flags_get(e->exe) & (ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR)))
+ {
+ /* We want to report the Last Words of the exe, so delay this event.
+ * This is twice as relevant for stderr.
+ * There are three possibilities here -
+ * 1 There are no Last Words.
+ * 2 There are Last Words, they are not ready to be read.
+ * 3 There are Last Words, they are ready to be read.
+ *
+ * For 1 we don't want to delay, for 3 we want to delay.
+ * 2 is the problem. If we check for data now and there
+ * is none, then there is no way to differentiate 1 and 2.
+ * If we don't delay, we may loose data, but if we do delay,
+ * there may not be data and the exit event never gets sent.
+ *
+ * Any way you look at it, there has to be some time passed
+ * before the exit event gets sent. So the strategy here is
+ * to setup a timer event that will send the exit event after
+ * an arbitrary, but brief, time.
+ *
+ * This is probably paranoid, for the less paraniod, we could
+ * check to see for Last Words, and only delay if there are any.
+ * This has it's own set of problems.
+ */
+ Ecore_Timer *doomsday_clock;
+
+ doomsday_clock = _ecore_exe_doomsday_clock_get(e->exe);
+ IF_FN_DEL(ecore_timer_del, doomsday_clock);
+ _ecore_exe_doomsday_clock_set(e->exe, ecore_timer_add(0.1, _ecore_signal_exe_exit_delay, e));
+ }
+ else
+ {
+ _ecore_event_add(ECORE_EXE_EVENT_DEL, e,
+ _ecore_exe_event_del_free, NULL);
+ }
+ }
+ }
+ sig_count--;
+ }
+ sigchld_count = 0;
+
+ if (sigusr1_count > MAXSIGQ)
+ WRN("%i SIGUSR1 in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sigusr1_count, MAXSIGQ);
+ for (n = 0; n < sigusr1_count; n++)
+ {
+ Ecore_Event_Signal_User *e;
+
+ e = _ecore_event_signal_user_new();
+ if (e)
+ {
+ e->number = 1;
+
+ if ((n < MAXSIGQ) && (sigusr1_info[n].si_signo))
+ e->data = sigusr1_info[n];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sigusr1_count = 0;
+
+ if (sigusr2_count > MAXSIGQ)
+ WRN("%i SIGUSR2 in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sigusr2_count, MAXSIGQ);
+ for (n = 0; n < sigusr2_count; n++)
+ {
+ Ecore_Event_Signal_User *e;
+
+ e = _ecore_event_signal_user_new();
+ if (e)
+ {
+ e->number = 2;
+
+ if ((n < MAXSIGQ) && (sigusr2_info[n].si_signo))
+ e->data = sigusr2_info[n];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sigusr2_count = 0;
+
+ if (sighup_count > MAXSIGQ)
+ WRN("%i SIGHUP in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sighup_count, MAXSIGQ);
+ for (n = 0; n < sighup_count; n++)
+ {
+ Ecore_Event_Signal_Hup *e;
+
+ e = _ecore_event_signal_hup_new();
+ if (e)
+ {
+ if ((n < MAXSIGQ) && (sighup_info[n].si_signo))
+ e->data = sighup_info[n];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sighup_count = 0;
+
+ if (sigquit_count > MAXSIGQ)
+ WRN("%i SIGQUIT in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sigquit_count, MAXSIGQ);
+ for (n = 0; n < sigquit_count; n++)
+ {
+ Ecore_Event_Signal_Exit *e;
+
+ e = _ecore_event_signal_exit_new();
+ if (e)
+ {
+ e->quit = 1;
+
+ if ((n < MAXSIGQ) && (sigquit_info[n].si_signo))
+ e->data = sigquit_info[n];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sigquit_count = 0;
+
+ if (sigint_count > MAXSIGQ)
+ WRN("%i SIGINT in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sigint_count, MAXSIGQ);
+ for (n = 0; n < sigint_count; n++)
+ {
+ Ecore_Event_Signal_Exit *e;
+
+ e = _ecore_event_signal_exit_new();
+ if (e)
+ {
+ e->interrupt = 1;
+
+ if ((n < MAXSIGQ) && (sigint_info[n].si_signo))
+ e->data = sigint_info[n];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sigint_count = 0;
+
+ if (sigterm_count > MAXSIGQ)
+ WRN("%i SIGTERM in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sigterm_count, MAXSIGQ);
+ for (n = 0; n < sigterm_count; n++)
+ {
+ Ecore_Event_Signal_Exit *e;
+
+ e = _ecore_event_signal_exit_new();
+ if (e)
+ {
+ e->terminate = 1;
+
+ if ((n < MAXSIGQ) && (sigterm_info[n].si_signo))
+ e->data = sigterm_info[n];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sigterm_count = 0;
+
+#ifdef SIGPWR
+ if (sigpwr_count > MAXSIGQ)
+ WRN("%i SIGPWR in queue. max queue size %i. losing "
+ "siginfo for extra signals.", sigpwr_count, MAXSIGQ);
+ for (n = 0; n < sigpwr_count; n++)
+ {
+ Ecore_Event_Signal_Power *e;
+
+ e = _ecore_event_signal_power_new();
+ if (e)
+ {
+ if ((n < MAXSIGQ) && (sigpwr_info[n].si_signo))
+ e->data = sigpwr_info[n];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sigpwr_count = 0;
+#endif
+
+#ifdef SIGRTMIN
+ for (i = 0; i < num; i++)
+ {
+ if (sigrt_count[i] > MAXSIGQ)
+ WRN("%i SIGRT%i in queue. max queue size %i. losing "
+ "siginfo for extra signals.", i + 1, sigrt_count[i], MAXSIGQ);
+ for (n = 0; n < sigrt_count[i]; n++)
+ {
+ Ecore_Event_Signal_Realtime *e;
+
+ if ((e = _ecore_event_signal_realtime_new()))
+ {
+ e->num = i;
+
+ if ((n < MAXSIGQ) && (sigrt_info[n][i].si_signo))
+ e->data = sigrt_info[n][i];
+
+ ecore_event_add(ECORE_EVENT_SIGNAL_REALTIME, e, NULL, NULL);
+ }
+ sig_count--;
+ }
+ sigrt_count[i] = 0;
+ }
+#endif
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+}
+
+static void
+_ecore_signal_callback_set(int sig, Signal_Handler func)
+{
+ struct sigaction sa;
+
+ sa.sa_sigaction = func;
+ sa.sa_flags = SA_RESTART | SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ sigaction(sig, &sa, NULL);
+}
+
+static void
+_ecore_signal_callback_ignore(int sig __UNUSED__, siginfo_t *si __UNUSED__, void *foo __UNUSED__)
+{
+}
+
+static void
+_ecore_signal_callback_sigchld(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigchld_info[n] = *si;
+ else
+ sigchld_info[n].si_signo = 0;
+ }
+
+ sigchld_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigusr1(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigusr1_info[n] = *si;
+ else
+ sigusr1_info[n].si_signo = 0;
+ }
+ sigusr1_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigusr2(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigusr2_info[n] = *si;
+ else
+ sigusr2_info[n].si_signo = 0;
+ }
+ sigusr2_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sighup(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sighup_info[n] = *si;
+ else
+ sighup_info[n].si_signo = 0;
+ }
+ sighup_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigquit(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigquit_info[n] = *si;
+ else
+ sigquit_info[n].si_signo = 0;
+ }
+ sigquit_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigint(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigint_info[n] = *si;
+ else
+ sigint_info[n].si_signo = 0;
+ }
+ sigint_count++;
+ sig_count++;
+}
+
+static void
+_ecore_signal_callback_sigterm(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigterm_info[n] = *si;
+ else
+ sigterm_info[n].si_signo = 0;
+ }
+ sigterm_count++;
+ sig_count++;
+}
+
+#ifdef SIGPWR
+static void
+_ecore_signal_callback_sigpwr(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigpwr_info[n] = *si;
+ else
+ sigpwr_info[n].si_signo = 0;
+ }
+ sigpwr_count++;
+ sig_count++;
+}
+#endif
+
+#ifdef SIGRTMIN
+static void
+_ecore_signal_callback_sigrt(int sig, siginfo_t *si, void *foo __UNUSED__)
+{
+ volatile sig_atomic_t n;
+ n = sigchld_count;
+ if (n < MAXSIGQ)
+ {
+ if (si)
+ sigrt_info[n][sig - SIGRTMIN] = *si;
+ else
+ sigrt_info[n][sig - SIGRTMIN].si_signo = 0;
+ }
+ sigrt_count[sig - SIGRTMIN]++;
+ sig_count++;
+}
+#endif
+
+static int
+_ecore_signal_exe_exit_delay(void *data)
+{
+ Ecore_Exe_Event_Del *e;
+
+ e = data;
+ if (e)
+ {
+ _ecore_exe_doomsday_clock_set(e->exe, NULL);
+ _ecore_event_add(ECORE_EXE_EVENT_DEL, e,
+ _ecore_exe_event_del_free, NULL);
+ }
+ return 0;
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#ifdef EFL_HAVE_PTHREAD
+# include <pthread.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#ifdef EFL_HAVE_PTHREAD
+typedef struct _Ecore_Pthread_Worker Ecore_Pthread_Worker;
+typedef struct _Ecore_Pthread_Data Ecore_Pthread_Data;
+typedef struct _Ecore_Pthread Ecore_Pthread;
+
+struct _Ecore_Pthread_Worker
+{
+ void (*func_heavy)(void *data);
+ void (*func_end)(void *data);
+ void (*func_cancel)(void *data);
+
+ const void *data;
+
+ Eina_Bool cancel : 1;
+};
+
+struct _Ecore_Pthread_Data
+{
+ Ecore_Pipe *p;
+ pthread_t thread;
+};
+#endif
+
+static int _ecore_thread_count_max = 0;
+static int ECORE_THREAD_PIPE_DEL = 0;
+
+#ifdef EFL_HAVE_PTHREAD
+static int _ecore_thread_count = 0;
+static Eina_List *_ecore_thread_data = NULL;
+static Eina_List *_ecore_thread = NULL;
+static Ecore_Event_Handler *del_handler = NULL;
+
+static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void
+_ecore_thread_pipe_free(void *data __UNUSED__, void *event)
+{
+ Ecore_Pipe *p = event;
+
+ ecore_pipe_del(p);
+}
+
+static int
+_ecore_thread_pipe_del(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+{
+ /* This is a hack to delay pipe destruction until we are out of it's internal loop. */
+ return 0;
+}
+
+static void
+_ecore_thread_end(Ecore_Pthread_Data *pth)
+{
+ Ecore_Pipe *p;
+
+ if (pthread_join(pth->thread, (void**) &p) != 0)
+ return ;
+
+ _ecore_thread = eina_list_remove(_ecore_thread, pth);
+
+ ecore_event_add(ECORE_THREAD_PIPE_DEL, pth->p, _ecore_thread_pipe_free, NULL);
+}
+
+static void *
+_ecore_thread_worker(Ecore_Pthread_Data *pth)
+{
+ Ecore_Pthread_Worker *work;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+ pthread_mutex_lock(&_mutex);
+ _ecore_thread_count++;
+ pthread_mutex_unlock(&_mutex);
+
+ on_error:
+
+ while (_ecore_thread_data)
+ {
+ pthread_mutex_lock(&_mutex);
+
+ if (!_ecore_thread_data)
+ {
+ pthread_mutex_unlock(&_mutex);
+ break;
+ }
+
+ work = eina_list_data_get(_ecore_thread_data);
+ _ecore_thread_data = eina_list_remove_list(_ecore_thread_data, _ecore_thread_data);
+
+ pthread_mutex_unlock(&_mutex);
+
+ work->func_heavy((void*) work->data);
+
+ ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker*));
+ }
+
+ pthread_mutex_lock(&_mutex);
+ if (_ecore_thread_data)
+ {
+ pthread_mutex_unlock(&_mutex);
+ goto on_error;
+ }
+ _ecore_thread_count--;
+
+ pthread_mutex_unlock(&_mutex);
+
+ work = malloc(sizeof (Ecore_Pthread_Worker));
+ if (!work) return NULL;
+
+ work->data = pth;
+ work->func_heavy = NULL;
+ work->func_end = (void*) _ecore_thread_end;
+ work->func_cancel = NULL;
+ work->cancel = EINA_FALSE;
+
+ ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker*));
+
+ return pth->p;
+}
+
+static void
+_ecore_thread_handler(void *data __UNUSED__, void *buffer, unsigned int nbyte)
+{
+ Ecore_Pthread_Worker *work;
+
+ if (nbyte != sizeof (Ecore_Pthread_Worker*)) return ;
+
+ work = *(Ecore_Pthread_Worker**)buffer;
+
+ if (work->cancel)
+ {
+ if (work->func_cancel)
+ work->func_cancel((void*) work->data);
+ }
+ else
+ {
+ work->func_end((void*) work->data);
+ }
+
+ free(work);
+}
+#endif
+
+void
+_ecore_thread_init(void)
+{
+ _ecore_thread_count_max = eina_cpu_count();
+ if (_ecore_thread_count_max <= 0)
+ _ecore_thread_count_max = 1;
+
+ ECORE_THREAD_PIPE_DEL = ecore_event_type_new();
+#ifdef EFL_HAVE_PTHREAD
+ del_handler = ecore_event_handler_add(ECORE_THREAD_PIPE_DEL, _ecore_thread_pipe_del, NULL);
+#endif
+}
+
+void
+_ecore_thread_shutdown(void)
+{
+ /* FIXME: If function are still running in the background, should we kill them ? */
+#ifdef EFL_HAVE_PTHREAD
+ Ecore_Pthread_Worker *work;
+ Ecore_Pthread_Data *pth;
+
+ pthread_mutex_lock(&_mutex);
+
+ EINA_LIST_FREE(_ecore_thread_data, work)
+ {
+ if (work->func_cancel)
+ work->func_cancel((void*)work->data);
+ free(work);
+ }
+
+ pthread_mutex_unlock(&_mutex);
+
+ EINA_LIST_FREE(_ecore_thread, pth)
+ {
+ Ecore_Pipe *p;
+
+ pthread_cancel(pth->thread);
+ pthread_join(pth->thread, (void **) &p);
+
+ ecore_pipe_del(pth->p);
+ }
+
+ ecore_event_handler_del(del_handler);
+ del_handler = NULL;
+#endif
+}
+
+/*
+ * ecore_thread_run provide a facility for easily managing heavy task in a
+ * parallel thread. You should provide two function, the first one, func_heavy,
+ * that will do the heavy work in another thread (so you should not use the
+ * EFL in it except Eina if you are carefull), and the second one, func_end,
+ * that will be called in Ecore main loop when func_heavy is done. So you
+ * can use all the EFL inside this function.
+ *
+ * Be aware, that you can't make assumption on the result order of func_end
+ * after many call to ecore_thread_run, as we start as much thread as the
+ * host CPU can handle.
+ */
+EAPI Ecore_Thread *
+ecore_thread_run(void (*func_heavy)(void *data),
+ void (*func_end)(void *data),
+ void (*func_cancel)(void *data),
+ const void *data)
+{
+#ifdef EFL_HAVE_PTHREAD
+ Ecore_Pthread_Worker *work;
+ Ecore_Pthread_Data *pth;
+
+ work = malloc(sizeof (Ecore_Pthread_Worker));
+ if (!work)
+ {
+ func_cancel((void*) data);
+ return NULL;
+ }
+
+ work->func_heavy = func_heavy;
+ work->func_end = func_end;
+ work->func_cancel = func_cancel;
+ work->cancel = EINA_FALSE;
+ work->data = data;
+
+ pthread_mutex_lock(&_mutex);
+ _ecore_thread_data = eina_list_append(_ecore_thread_data, work);
+
+ if (_ecore_thread_count == _ecore_thread_count_max)
+ {
+ pthread_mutex_unlock(&_mutex);
+ return (Ecore_Thread*) work;
+ }
+
+ pthread_mutex_unlock(&_mutex);
+
+ /* One more thread could be created. */
+ pth = malloc(sizeof (Ecore_Pthread_Data));
+ if (!pth)
+ goto on_error;
+
+ pth->p = ecore_pipe_add(_ecore_thread_handler, NULL);
+
+ if (pthread_create(&pth->thread, NULL, (void*) _ecore_thread_worker, pth) == 0)
+ return (Ecore_Thread*) work;
+
+ on_error:
+ if (_ecore_thread_count == 0)
+ {
+ if (work->func_cancel)
+ work->func_cancel((void*) work->data);
+ free(work);
+ }
+ return NULL;
+#else
+ /*
+ If no thread and as we don't want to break app that rely on this
+ facility, we will lock the interface until we are done.
+ */
+ func_heavy((void *)data);
+ func_end((void *)data);
+
+ return NULL;
+#endif
+}
+
+/*
+ * ecore_thread_cancel give the possibility to cancel a task still running. It
+ * will return EINA_FALSE, if the destruction is delayed or EINA_TRUE if it is
+ * cancelled after this call.
+ *
+ * You should use this function only in the main loop.
+ *
+ * func_end, func_cancel will destroy the handler, so don't use it after.
+ * And if ecore_thread_cancel return EINA_TRUE, you should not use Ecore_Thread also.
+ */
+EAPI Eina_Bool
+ecore_thread_cancel(Ecore_Thread *thread)
+{
+#ifdef EFL_HAVE_PTHREAD
+ Ecore_Pthread_Worker *work;
+ Eina_List *l;
+
+ pthread_mutex_lock(&_mutex);
+
+ EINA_LIST_FOREACH(_ecore_thread_data, l, work)
+ if ((void*) work == (void*) thread)
+ {
+ _ecore_thread_data = eina_list_remove_list(_ecore_thread_data, l);
+
+ pthread_mutex_unlock(&_mutex);
+
+ if (work->func_cancel)
+ work->func_cancel((void*) work->data);
+ free(work);
+
+ return EINA_TRUE;
+ }
+
+ pthread_mutex_unlock(&_mutex);
+
+ /* Delay the destruction */
+ ((Ecore_Pthread_Worker*)thread)->cancel = EINA_TRUE;
+ return EINA_FALSE;
+#else
+ return EINA_TRUE;
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+
+/* FIXME: clock_gettime() is an option... */
+
+/**
+ * Retrieves the current system time as a floating point value in seconds.
+ *
+ * Also see ecore_loop_time_get().
+ *
+ * @return The number of seconds since 12.00AM 1st January 1970.
+ * @ingroup Ecore_Time_Group
+ */
+EAPI double
+ecore_time_get(void)
+{
+#ifdef HAVE_EVIL
+ return evil_time_get();
+#else
+# ifdef HAVE_GETTIMEOFDAY
+ struct timeval timev;
+
+ gettimeofday(&timev, NULL);
+ return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
+# else
+# error "Your platform isn't supported yet"
+# endif
+#endif
+}
+
+double _ecore_loop_time = -1.0;
+
+/**
+ * Retrieves the time at which the last loop stopped waiting for timeouts or events
+ *
+ * This gets the time (since Jan 1st, 1970, 12:00AM) that the main loop ceased
+ * waiting for timouts and/or events to come in or for signals or any other
+ * interrupt source. This should be considered a reference point for all
+ * time based activity that should calculate its timepoint from the return
+ * of ecore_loop_time_get(). use this UNLESS you absolutely must get the
+ * current actual timepoint - then use ecore_time_get(). If this is called
+ * before any loop has ever been run, then it will call ecore_time_get() for
+ * you the first time and thus have an initial time reference.
+ *
+ * @return The number of seconds since 12.00AM 1st January 1970.
+ * @ingroup Ecore_Time_Group
+ */
+EAPI double
+ecore_loop_time_get(void)
+{
+ return _ecore_loop_time;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+
+struct _Ecore_Timer
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ double in;
+ double at;
+ double pending;
+ int (*func) (void *data);
+ void *data;
+
+ int references;
+ unsigned char delete_me : 1;
+ unsigned char just_added : 1;
+ unsigned char frozen : 1;
+};
+
+
+static void _ecore_timer_set(Ecore_Timer *timer, double at, double in, int (*func) (void *data), void *data);
+
+static int timers_added = 0;
+static int timers_delete_me = 0;
+static Ecore_Timer *timers = NULL;
+static Ecore_Timer *timer_current = NULL;
+static Ecore_Timer *suspended = NULL;
+static double last_check = 0.0;
+static double precision = 10.0 / 1000000.0;
+
+/**
+ * @defgroup Ecore_Time_Group Ecore Time Functions
+ *
+ * Functions that deal with time. These functions include those that simply
+ * retrieve it in a given format, and those that create events based on it.
+ */
+
+/**
+ * Retrieves the current precision used by timer infrastructure.
+ *
+ * @see ecore_timer_precision_set()
+ */
+EAPI double
+ecore_timer_precision_get(void)
+{
+ return precision;
+}
+
+/**
+ * Sets the precision to be used by timer infrastructure.
+ *
+ * When system calculates time to expire the next timer we'll be able
+ * to delay the timer by the given amount so more timers will fit in
+ * the same dispatch, waking up the system less often and thus being
+ * able to save power.
+ *
+ * Be aware that kernel may delay delivery even further, these delays
+ * are always possible due other tasks having higher priorities or
+ * other scheduler policies.
+ *
+ * Example:
+ * We have 2 timers, one that expires in a 2.0s and another that
+ * expires in 2.1s, if precision is 0.1s, then the Ecore will request
+ * for the next expire to happen in 2.1s and not 2.0s and another one
+ * of 0.1 as it would before.
+ *
+ * @note Ecore is smart enough to see if there are timers in the
+ * precision range, if it does not, in our example if no second timer
+ * in (T + precision) existed, then it would use the minimum timeout.
+ *
+ * @param value allowed introduced timeout delay, in seconds.
+ */
+EAPI void
+ecore_timer_precision_set(double value)
+{
+ if (value < 0.0)
+ {
+ ERR("Precision %f less than zero, ignored", value);
+ return;
+ }
+ precision = value;
+}
+
+/**
+ * Creates a timer to call the given function in the given period of time.
+ * @param in The interval in seconds.
+ * @param func The given function. If @p func returns 1, the timer is
+ * rescheduled for the next interval @p in.
+ * @param data Data to pass to @p func when it is called.
+ * @return A timer object on success. @c NULL on failure.
+ * @ingroup Ecore_Time_Group
+ *
+ * This function adds a timer and returns its handle on success and NULL on
+ * failure. The function @p func will be called every @p in seconds. The
+ * function will be passed the @p data pointer as its parameter.
+ *
+ * When the timer @p func is called, it must return a value of either 1
+ * (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL).
+ * If it returns 1, it will be called again at the next tick, or if it returns
+ * 0 it will be deleted automatically making any references/handles for it
+ * invalid.
+ */
+EAPI Ecore_Timer *
+ecore_timer_add(double in, int (*func) (void *data), const void *data)
+{
+ double now;
+ Ecore_Timer *timer;
+
+ if (!func) return NULL;
+ if (in < 0.0) in = 0.0;
+ timer = calloc(1, sizeof(Ecore_Timer));
+ if (!timer) return NULL;
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
+ now = ecore_time_get();
+ _ecore_timer_set(timer, now + in, in, func, (void *)data);
+ return timer;
+}
+
+/**
+ * Creates a timer to call the given function in the given period of time.
+ * @param in The interval in seconds from current loop time.
+ * @param func The given function. If @p func returns 1, the timer is
+ * rescheduled for the next interval @p in.
+ * @param data Data to pass to @p func when it is called.
+ * @return A timer object on success. @c NULL on failure.
+ * @ingroup Ecore_Time_Group
+ *
+ * This is the same as ecore_timer_add(), but "now" is the time from
+ * ecore_loop_time_get() not ecore_time_get() as ecore_timer_add() uses. See
+ * ecore_timer_add() for more details.
+ */
+EAPI Ecore_Timer *
+ecore_timer_loop_add(double in, int (*func) (void *data), const void *data)
+{
+ double now;
+ Ecore_Timer *timer;
+
+ if (!func) return NULL;
+ if (in < 0.0) in = 0.0;
+ timer = calloc(1, sizeof(Ecore_Timer));
+ if (!timer) return NULL;
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
+ now = ecore_loop_time_get();
+ _ecore_timer_set(timer, now + in, in, func, (void *)data);
+ return timer;
+}
+
+/**
+ * Delete the specified timer from the timer list.
+ * @param timer The timer to delete.
+ * @return The data pointer set for the timer when @ref ecore_timer_add was
+ * called. @c NULL is returned if the function is unsuccessful.
+ * @ingroup Ecore_Time_Group
+ *
+ * Note: @p timer must be a valid handle. If the timer function has already
+ * returned 0, the handle is no longer valid (and does not need to be delete).
+ */
+EAPI void *
+ecore_timer_del(Ecore_Timer *timer)
+{
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_del");
+ return NULL;
+ }
+
+ if (timer->frozen && !timer->references)
+ {
+ void *data = timer->data;
+
+ suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+
+ if (timer->delete_me)
+ timers_delete_me--;
+
+ free(timer);
+ return data;
+ }
+
+ if (timer->delete_me) return timer->data;
+ timers_delete_me++;
+ timer->delete_me = 1;
+ return timer->data;
+}
+
+/**
+ * Change the interval the timer ticks of. If set during
+ * a timer call, this will affect the next interval.
+ *
+ * @param timer The timer to change.
+ * @param in The interval in seconds.
+ * @ingroup Ecore_Time_Group
+ */
+EAPI void
+ecore_timer_interval_set(Ecore_Timer *timer, double in)
+{
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_interval_set");
+ return;
+ }
+ timer->in = in;
+}
+
+/**
+ * Get the interval the timer ticks on.
+ *
+ * @param timer The timer to retrieve the interval from
+ * @return The interval on success. -1 on failure.
+ * @ingroup Ecore_Time_Group
+ */
+EAPI double
+ecore_timer_interval_get(Ecore_Timer *timer)
+{
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_interval_get");
+ return -1.0;
+ }
+
+ return timer->in;
+}
+
+/**
+ * Add some delay for the next occurence of a timer.
+ * This doesn't affect the interval of a timer.
+ *
+ * @param timer The timer to change.
+ * @param add The dalay to add to the next iteration.
+ * @ingroup Ecore_Time_Group
+ */
+EAPI void
+ecore_timer_delay(Ecore_Timer *timer, double add)
+{
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_delay");
+ return;
+ }
+
+ if (timer->frozen)
+ {
+ timer->pending += add;
+ }
+ else
+ {
+ timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ _ecore_timer_set(timer, timer->at + add, timer->in, timer->func, timer->data);
+ }
+}
+
+/**
+ * Get the pending time regarding a timer.
+ *
+ * @param timer The timer to learn from.
+ * @ingroup Ecore_Time_Group
+ */
+EAPI double
+ecore_timer_pending_get(Ecore_Timer *timer)
+{
+ double now;
+
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_pending_get");
+ return 0;
+ }
+
+ now = ecore_time_get();
+
+ if (timer->frozen)
+ return timer->pending;
+ return timer->at - now;
+}
+
+/**
+ *
+ *
+ */
+EAPI void
+ecore_timer_freeze(Ecore_Timer *timer)
+{
+ double now;
+
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_freeze");
+ return ;
+ }
+
+ /* Timer already frozen */
+ if (timer->frozen)
+ return ;
+
+ timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ suspended = (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+
+ now = ecore_time_get();
+
+ timer->pending = timer->at - now;
+ timer->at = 0.0;
+ timer->frozen = 1;
+}
+
+EAPI void
+ecore_timer_thaw(Ecore_Timer *timer)
+{
+ double now;
+
+ if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
+ {
+ ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
+ "ecore_timer_thaw");
+ return ;
+ }
+
+ /* Timer not frozen */
+ if (!timer->frozen)
+ return ;
+
+ suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+ now = ecore_time_get();
+
+ _ecore_timer_set(timer, timer->pending + now, timer->in, timer->func, timer->data);
+}
+
+void
+_ecore_timer_shutdown(void)
+{
+ Ecore_Timer *timer;
+
+ while ((timer = timers))
+ {
+ timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timers));
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
+ free(timer);
+ }
+
+ while ((timer = suspended))
+ {
+ suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(suspended));
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
+ free(timer);
+ }
+
+ timer_current = NULL;
+}
+
+void
+_ecore_timer_cleanup(void)
+{
+ Ecore_Timer *l;
+ int in_use = 0;
+
+ if (!timers_delete_me) return;
+ for (l = timers; l;)
+ {
+ Ecore_Timer *timer = l;
+
+ l = (Ecore_Timer *) EINA_INLIST_GET(l)->next;
+ if (timer->delete_me)
+ {
+ if (timer->references)
+ {
+ in_use++;
+ continue;
+ }
+ timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
+ free(timer);
+ timers_delete_me--;
+ if (timers_delete_me == 0) return;
+ }
+ }
+ for (l = suspended; l;)
+ {
+ Ecore_Timer *timer = l;
+
+ l = (Ecore_Timer *) EINA_INLIST_GET(l)->next;
+ if (timer->delete_me)
+ {
+ if (timer->references)
+ {
+ in_use++;
+ continue;
+ }
+ suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
+ free(timer);
+ timers_delete_me--;
+ if (timers_delete_me == 0) return;
+ }
+ }
+
+ if ((!in_use) && (timers_delete_me))
+ {
+ ERR("%d timers to delete, but they were not found! reset counter.",
+ timers_delete_me);
+ timers_delete_me = 0;
+ }
+}
+
+void
+_ecore_timer_enable_new(void)
+{
+ Ecore_Timer *timer;
+
+ if (!timers_added) return;
+ timers_added = 0;
+ EINA_INLIST_FOREACH(timers, timer) timer->just_added = 0;
+}
+
+int
+_ecore_timers_exists(void)
+{
+ Ecore_Timer *timer = timers;
+
+ while ((timer) && (timer->delete_me))
+ timer = (Ecore_Timer *)EINA_INLIST_GET(timer)->next;
+
+ return !!timer;
+}
+
+static inline Ecore_Timer *
+_ecore_timer_first_get(void)
+{
+ Ecore_Timer *timer = timers;
+
+ while ((timer) && ((timer->delete_me) || (timer->just_added)))
+ timer = (Ecore_Timer *) EINA_INLIST_GET(timer)->next;
+
+ return timer;
+}
+
+static inline Ecore_Timer *
+_ecore_timer_after_get(Ecore_Timer *base)
+{
+ Ecore_Timer *timer = (Ecore_Timer *) EINA_INLIST_GET(base)->next;
+ double maxtime = base->at + precision;
+
+ while ((timer) && ((timer->delete_me) || (timer->just_added)) && (timer->at <= maxtime))
+ timer = (Ecore_Timer *) EINA_INLIST_GET(timer)->next;
+
+ if ((!timer) || (timer->at > maxtime))
+ return NULL;
+
+ return timer;
+}
+
+double
+_ecore_timer_next_get(void)
+{
+ double now;
+ double in;
+ Ecore_Timer *first, *second;
+
+ first = _ecore_timer_first_get();
+ if (!first) return -1;
+
+ second = _ecore_timer_after_get(first);
+ if (second)
+ first = second;
+
+ now = ecore_loop_time_get();
+ in = first->at - now;
+ if (in < 0) in = 0;
+ return in;
+}
+
+int
+_ecore_timer_call(double when)
+{
+ if (!timers) return 0;
+ if (last_check > when)
+ {
+ Ecore_Timer *timer;
+ /* User set time backwards */
+ EINA_INLIST_FOREACH(timers, timer) timer->at -= (last_check - when);
+ }
+ last_check = when;
+
+ if (!timer_current)
+ {
+ /* regular main loop, start from head */
+ timer_current = timers;
+ }
+ else
+ {
+ /* recursive main loop, continue from where we were */
+ timer_current = (Ecore_Timer *)EINA_INLIST_GET(timer_current)->next;
+ }
+
+ while (timer_current)
+ {
+ Ecore_Timer *timer = timer_current;
+
+ if (timer->at > when)
+ {
+ timer_current = NULL; /* ended walk, next should restart. */
+ return 0;
+ }
+
+ if ((timer->just_added) || (timer->delete_me))
+ {
+ timer_current = (Ecore_Timer*)EINA_INLIST_GET(timer_current)->next;
+ continue;
+ }
+
+ timer->references++;
+ if (!timer->func(timer->data)) ecore_timer_del(timer);
+ timer->references--;
+
+ if (timer_current) /* may have changed in recursive main loops */
+ timer_current = (Ecore_Timer *)EINA_INLIST_GET(timer_current)->next;
+
+ if ((!timer->delete_me) && (!timer->frozen))
+ {
+ timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+
+ /* if the timer would have gone off more than 15 seconds ago,
+ * assume that the system hung and set the timer to go off
+ * timer->in from now. this handles system hangs, suspends
+ * and more, so ecore will only "replay" the timers while
+ * the system is suspended if it is suspended for less than
+ * 15 seconds (basically). this also handles if the process
+ * is stopped in a debugger or IO and other handling gets
+ * really slow within the main loop.
+ */
+ if ((timer->at + timer->in) < (when - 15.0))
+ _ecore_timer_set(timer, when + timer->in, timer->in, timer->func, timer->data);
+ else
+ _ecore_timer_set(timer, timer->at + timer->in, timer->in, timer->func, timer->data);
+ }
+ }
+ return 0;
+}
+
+static void
+_ecore_timer_set(Ecore_Timer *timer, double at, double in, int (*func) (void *data), void *data)
+{
+ Ecore_Timer *t2;
+
+ timers_added = 1;
+ timer->at = at;
+ timer->in = in;
+ timer->func = func;
+ timer->data = data;
+ timer->just_added = 1;
+ timer->frozen = 0;
+ timer->pending = 0.0;
+ if (timers)
+ {
+ EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(timers), t2)
+ {
+ if (timer->at > t2->at)
+ {
+ timers = (Ecore_Timer *) eina_inlist_append_relative(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer), EINA_INLIST_GET(t2));
+ return;
+ }
+ }
+ }
+ timers = (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+}
--- /dev/null
+/*
+* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+*/
+
+#ifndef _ECORE_COCOA_H
+#define _ECORE_COCOA_H
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _Ecore_Cocoa_Window Ecore_Cocoa_Window;
+
+EAPI extern int ECORE_COCOA_EVENT_GOT_FOCUS;
+EAPI extern int ECORE_COCOA_EVENT_LOST_FOCUS;
+EAPI extern int ECORE_COCOA_EVENT_RESIZE;
+EAPI extern int ECORE_COCOA_EVENT_EXPOSE;
+
+typedef struct _Ecore_Cocoa_Event_Video_Resize Ecore_Cocoa_Event_Video_Resize;
+struct _Ecore_Cocoa_Event_Video_Resize
+{
+ int w;
+ int h;
+};
+
+
+/* Core */
+
+EAPI int ecore_cocoa_init(const char *name);
+EAPI int ecore_cocoa_shutdown(void);
+EAPI void ecore_cocoa_feed_events(void);
+
+/* Window */
+
+EAPI Ecore_Cocoa_Window *ecore_cocoa_window_new(int x,
+ int y,
+ int width,
+ int height);
+
+EAPI void ecore_cocoa_window_free(Ecore_Cocoa_Window *window);
+
+EAPI void *ecore_cocoa_window_hwnd_get(Ecore_Cocoa_Window *window);
+
+EAPI void ecore_cocoa_window_move(Ecore_Cocoa_Window *window,
+ int x,
+ int y);
+
+EAPI void ecore_cocoa_window_resize(Ecore_Cocoa_Window *window,
+ int width,
+ int height);
+
+EAPI void ecore_cocoa_window_move_resize(Ecore_Cocoa_Window *window,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI void ecore_cocoa_window_geometry_get(Ecore_Cocoa_Window *window,
+ int *x,
+ int *y,
+ int *width,
+ int *height);
+
+EAPI void ecore_cocoa_window_size_get(Ecore_Cocoa_Window *window,
+ int *width,
+ int *height);
+
+EAPI void ecore_cocoa_window_size_min_set(Ecore_Cocoa_Window *window,
+ unsigned int min_width,
+ unsigned int min_height);
+
+EAPI void ecore_cocoa_window_size_min_get(Ecore_Cocoa_Window *window,
+ unsigned int *min_width,
+ unsigned int *min_height);
+
+EAPI void ecore_cocoa_window_size_max_set(Ecore_Cocoa_Window *window,
+ unsigned int max_width,
+ unsigned int max_height);
+
+EAPI void ecore_cocoa_window_size_max_get(Ecore_Cocoa_Window *window,
+ unsigned int *max_width,
+ unsigned int *max_height);
+
+EAPI void ecore_cocoa_window_size_base_set(Ecore_Cocoa_Window *window,
+ unsigned int base_width,
+ unsigned int base_height);
+
+EAPI void ecore_cocoa_window_size_base_get(Ecore_Cocoa_Window *window,
+ unsigned int *base_width,
+ unsigned int *base_height);
+
+EAPI void ecore_cocoa_window_size_step_set(Ecore_Cocoa_Window *window,
+ unsigned int step_width,
+ unsigned int step_height);
+
+EAPI void ecore_cocoa_window_size_step_get(Ecore_Cocoa_Window *window,
+ unsigned int *step_width,
+ unsigned int *step_height);
+
+EAPI void ecore_cocoa_window_show(Ecore_Cocoa_Window *window);
+
+EAPI void ecore_cocoa_window_hide(Ecore_Cocoa_Window *window);
+
+EAPI void ecore_cocoa_window_raise(Ecore_Cocoa_Window *window);
+
+EAPI void ecore_cocoa_window_lower(Ecore_Cocoa_Window *window);
+
+EAPI void ecore_cocoa_window_title_set(Ecore_Cocoa_Window *window,
+ const char *title);
+
+EAPI void ecore_cocoa_window_focus_set(Ecore_Cocoa_Window *window);
+
+EAPI void ecore_cocoa_window_iconified_set(Ecore_Cocoa_Window *window,
+ int on);
+
+EAPI void ecore_cocoa_window_borderless_set(Ecore_Cocoa_Window *window,
+ int on);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+#ifndef ECORE_COCOA_KEYS_H__
+#define ECORE_COCOA_KEYS_H__
+
+struct _ecore_cocoa_keys_s
+{
+ int code;
+ const char *name;
+ const char *compose;
+};
+
+static const struct _ecore_cocoa_keys_s keystable[] =
+{
+
+{ 0, "0x00", "" },
+{ 0, "First", "" },
+{ 3, "Return", "\015" },
+{ 8, "BackSpace", "\010" },
+{ 9, "Tab", "\011" },
+{ 12, "Clear", "" },
+{ 13, "Return", "\015" },
+{ 19, "Pause", "" },
+{ 25, "BackTab", ""},
+{ 27, "Escape", "" },
+{ 32, "space", " " },
+{ 33, "exclam", "!" },
+{ 34, "quotedbl", "\"" },
+{ 35, "numbersign", "#" },
+{ 36, "dollar", "$" },
+{ 37, "percent", "%%" },
+{ 38, "ampersand", "&" },
+{ 39, "apostrophe", "'" },
+{ 40, "parenleft", "(" },
+{ 41, "parenright", ")" },
+{ 42, "asterik", "*" },
+{ 43, "plus", "+" },
+{ 44, "comma", "," },
+{ 45, "minus", "-" },
+{ 46, "period", "." },
+{ 47, "slash", "/" },
+{ 48, "0", "0" },
+{ 49, "1", "1" },
+{ 50, "2", "2" },
+{ 51, "3", "3" },
+{ 52, "4", "4" },
+{ 53, "5", "5" },
+{ 54, "6", "6" },
+{ 55, "7", "7" },
+{ 56, "8", "8" },
+{ 57, "9", "9" },
+{ 58, "colon", ";" },
+{ 59, "semicolon", ";" },
+{ 60, "less", "<" },
+{ 61, "equal", "=" },
+{ 62, "greater", ">" },
+{ 63, "question", "?" },
+{ 64, "at", "@" },
+
+{ 91, "bracketleft", "[" },
+{ 92, "backslash", "\\" },
+{ 93, "bracketright", "]" },
+{ 94, "asciicircumm", "^" },
+{ 95, "underscore", "_" },
+{ 96, "backquote", "`" },
+{ 97, "a", "a" },
+{ 98, "b", "b" },
+{ 99, "c", "c" },
+{ 100, "d", "d" },
+{ 101, "e", "e" },
+{ 102, "f", "f" },
+{ 103, "g", "g" },
+{ 104, "h", "h" },
+{ 105, "i", "i" },
+{ 106, "j", "j" },
+{ 107, "k", "k" },
+{ 108, "l", "l" },
+{ 109, "m", "m" },
+{ 110, "n", "n" },
+{ 111, "o", "o" },
+{ 112, "p", "p" },
+{ 113, "q", "q" },
+{ 114, "r", "r" },
+{ 115, "s", "s" },
+{ 116, "t", "t" },
+{ 117, "u", "u" },
+{ 118, "v", "v" },
+{ 119, "w", "w" },
+{ 120, "x", "x" },
+{ 121, "y", "y" },
+{ 122, "z", "z" },
+{ 123, "braceleft", "" },
+{ 124, "pipe", "" },
+{ 125, "braceright", "" },
+{ 127, "Delete", "\177" },
+{ 126, "asciitilde", "~" },
+
+{ 160, "w0", "" },
+{ 161, "w1", "" },
+{ 162, "w2", "" },
+{ 163, "w3", "" },
+{ 164, "w4", "" },
+{ 165, "w5", "" },
+{ 166, "w6", "" },
+{ 167, "w7", "" },
+{ 168, "w8", "" },
+{ 169, "w9", "" },
+{ 170, "w10", "" },
+{ 171, "w11", "" },
+{ 172, "w12", "" },
+{ 173, "w13", "" },
+{ 174, "w14", "" },
+{ 175, "w15", "" },
+{ 176, "w16", "" },
+{ 177, "w17", "" },
+{ 178, "w18", "" },
+{ 179, "w19", "" },
+{ 180, "w20", "" },
+{ 181, "w21", "" },
+{ 182, "w22", "" },
+{ 183, "w23", "" },
+{ 184, "w24", "" },
+{ 185, "w25", "" },
+{ 186, "w26", "" },
+{ 187, "w27", "" },
+{ 188, "w28", "" },
+{ 189, "w29", "" },
+{ 190, "w30", "" },
+{ 191, "w31", "" },
+{ 192, "w32", "" },
+{ 193, "w33", "" },
+{ 194, "w34", "" },
+{ 195, "w35", "" },
+{ 196, "w36", "" },
+{ 197, "w37", "" },
+{ 198, "w38", "" },
+{ 199, "w39", "" },
+{ 200, "w40", "" },
+{ 201, "w41", "" },
+{ 202, "w42", "" },
+{ 203, "w43", "" },
+{ 204, "w44", "" },
+{ 205, "w45", "" },
+{ 206, "w46", "" },
+{ 207, "w47", "" },
+{ 208, "w48", "" },
+{ 209, "w49", "" },
+{ 210, "w50", "" },
+{ 211, "w51", "" },
+{ 212, "w52", "" },
+{ 213, "w53", "" },
+{ 214, "w54", "" },
+{ 215, "w55", "" },
+{ 216, "w56", "" },
+{ 217, "w57", "" },
+{ 218, "w58", "" },
+{ 219, "w59", "" },
+{ 220, "w60", "" },
+{ 221, "w61", "" },
+{ 222, "w62", "" },
+{ 223, "w63", "" },
+{ 224, "w64", "" },
+{ 225, "w65", "" },
+{ 226, "w66", "" },
+{ 227, "w67", "" },
+{ 228, "w68", "" },
+{ 229, "w69", "" },
+{ 230, "w70", "" },
+{ 231, "w71", "" },
+{ 232, "w72", "" },
+{ 233, "w73", "" },
+{ 234, "w74", "" },
+{ 235, "w75", "" },
+{ 236, "w76", "" },
+{ 237, "w77", "" },
+{ 238, "w78", "" },
+{ 239, "w79", "" },
+{ 240, "w80", "" },
+{ 241, "w81", "" },
+{ 242, "w82", "" },
+{ 243, "w83", "" },
+{ 244, "w84", "" },
+{ 245, "w85", "" },
+{ 246, "w86", "" },
+{ 247, "w87", "" },
+{ 248, "w88", "" },
+{ 249, "w89", "" },
+{ 250, "w90", "" },
+{ 251, "w91", "" },
+{ 252, "w92", "" },
+{ 253, "w93", "" },
+{ 254, "w94", "" },
+{ 255, "w95", "" },
+
+{ 256, "KP0", "0" },
+{ 257, "KP1", "1" },
+{ 258, "KP2", "2" },
+{ 259, "KP3", "3" },
+{ 260, "KP4", "4" },
+{ 261, "KP5", "5" },
+{ 262, "KP6", "6" },
+{ 263, "KP7", "7" },
+{ 264, "KP8", "8" },
+{ 265, "KP9", "9" },
+{ 266, "period", "." },
+{ 267, "KP_Divide", "/" },
+{ 268, "KP_Multiply", "*" },
+{ 269, "KP_Minus", "-" },
+{ 270, "KP_Plus", "+" },
+{ 271, "KP_Enter", "\015" },
+{ 272, "KP_Equals", "=" },
+
+{ NSUpArrowFunctionKey, "Up", "" },
+{ NSDownArrowFunctionKey, "Down", "" },
+{ NSRightArrowFunctionKey, "Right", "" },
+{ NSLeftArrowFunctionKey, "Left", "" },
+{ NSInsertFunctionKey, "Insert", "" },
+{ NSHomeFunctionKey, "Home", "" },
+{ NSEndFunctionKey, "End", "" },
+{ NSPageUpFunctionKey, "Page_Up", "" },
+{ NSPageDownFunctionKey, "Page_Down", "" },
+
+{ NSF1FunctionKey, "F1", "" },
+{ NSF2FunctionKey, "F2", "" },
+{ NSF3FunctionKey, "F3", "" },
+{ NSF4FunctionKey, "F4", "" },
+{ NSF5FunctionKey, "F5", "" },
+{ NSF6FunctionKey, "F6", "" },
+{ NSF7FunctionKey, "F7", "" },
+{ NSF8FunctionKey, "F8", "" },
+{ NSF9FunctionKey, "F9", "" },
+{ NSF10FunctionKey, "F10", "" },
+{ NSF11FunctionKey, "F11", "" },
+{ NSF12FunctionKey, "F12", "" },
+{ NSF13FunctionKey, "F13", "" },
+{ NSF14FunctionKey, "F14", "" },
+{ NSF15FunctionKey, "F15", "" },
+{ NSF16FunctionKey, "F16", "" },
+{ NSF17FunctionKey, "F17", "" },
+{ NSF18FunctionKey, "F18", "" },
+{ NSF19FunctionKey, "F19", "" },
+{ NSF20FunctionKey, "F20", "" },
+{ NSF21FunctionKey, "F21", "" },
+{ NSF22FunctionKey, "F22", "" },
+{ NSF23FunctionKey, "F23", "" },
+{ NSF24FunctionKey, "F24", "" },
+{ NSF25FunctionKey, "F25", "" },
+{ NSF26FunctionKey, "F26", "" },
+{ NSF27FunctionKey, "F27", "" },
+{ NSF28FunctionKey, "F28", "" },
+{ NSF29FunctionKey, "F29", "" },
+{ NSF30FunctionKey, "F30", "" },
+{ NSF31FunctionKey, "F31", "" },
+{ NSF32FunctionKey, "F32", "" },
+{ NSF33FunctionKey, "F33", "" },
+{ NSF34FunctionKey, "F34", "" },
+{ NSF35FunctionKey, "F35", "" },
+
+{ NSClearLineFunctionKey, "Num_Lock", "" },
+{ 301, "Caps_Lock", "" },
+{ NSScrollLockFunctionKey, "Scroll_Lock", "" },
+{ 303, "Shift_R", "" },
+{ 304, "Shift_L", "" },
+{ 305, "Control_R", "" },
+{ 306, "Control_L", "" },
+{ 307, "Alt_R", "" },
+{ 308, "Alt_L", "" },
+{ 309, "Meta_R", "" },
+{ 310, "Meta_L", "" },
+{ 311, "Super_L", "" },
+{ 312, "Super_R", "" },
+
+{ NSModeSwitchFunctionKey, "Mode", "" },
+{ 314, "Compose", "" },
+
+{ NSHelpFunctionKey, "Help", "" },
+{ NSPrintFunctionKey, "Print", "" },
+{ NSSysReqFunctionKey, "SysReq", "" },
+{ NSBreakFunctionKey, "Break", "" },
+{ NSMenuFunctionKey, "Menu", "" },
+{ 320, "Power", "" },
+{ 321, "Euro", "" },
+{ NSUndoFunctionKey, "Undo", "" }
+
+};
+
+#endif /* ECORE_COCOA_KEYS_H__ */
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_input \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@
+
+if BUILD_ECORE_COCOA
+
+lib_LTLIBRARIES = libecore_cocoa.la
+include_HEADERS = \
+Ecore_Cocoa.h \
+Ecore_Cocoa_Keys.h
+
+libecore_cocoa_la_SOURCES = \
+ecore_cocoa.m \
+ecore_cocoa_window.m
+
+libecore_cocoa_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+@EVAS_LIBS@ \
+@EINA_LIBS@
+
+libecore_cocoa_la_LDFLAGS = @cocoa_ldflags@ -version-info @version_info@ @ecore_cocoa_release_info@
+
+endif
+
+EXTRA_DIST = ecore_cocoa_private.h
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Cocoa/Cocoa.h>
+
+#include <Eina.h>
+
+#include <Ecore.h>
+#include <ecore_private.h>
+#include <Ecore_Input.h>
+
+#include "Ecore_Cocoa.h"
+#include "Ecore_Cocoa_Keys.h"
+
+EAPI int ECORE_COCOA_EVENT_GOT_FOCUS = 0;
+EAPI int ECORE_COCOA_EVENT_LOST_FOCUS = 0;
+EAPI int ECORE_COCOA_EVENT_RESIZE = 0;
+EAPI int ECORE_COCOA_EVENT_EXPOSE = 0;
+
+static int _ecore_cocoa_init_count = 0;
+
+static int old_flags;
+
+EAPI int
+ecore_cocoa_init(const char *name __UNUSED__)
+{
+ if (++_ecore_cocoa_init_count != 1)
+ return _ecore_cocoa_init_count;
+
+ if (!ecore_event_init())
+ return --_ecore_cocoa_init_count;
+
+ ECORE_COCOA_EVENT_GOT_FOCUS = ecore_event_type_new();
+ ECORE_COCOA_EVENT_LOST_FOCUS = ecore_event_type_new();
+ ECORE_COCOA_EVENT_RESIZE = ecore_event_type_new();
+ ECORE_COCOA_EVENT_EXPOSE = ecore_event_type_new();
+
+ return _ecore_cocoa_init_count;
+}
+
+/**
+ * Shuts down the Ecore_Cocoa library.
+ * @return @c The number of times the system has been initialised without
+ * being shut down.
+ * @ingroup Ecore_Cocoa_Library_Group
+ */
+EAPI int
+ecore_cocoa_shutdown(void)
+{
+ if (--_ecore_cocoa_init_count != 0)
+ return _ecore_cocoa_init_count;
+
+ ecore_event_shutdown();
+
+ return _ecore_cocoa_init_count;
+}
+
+EAPI void
+ecore_cocoa_feed_events(void)
+{
+ NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0.001];
+ NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:date
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ [date release];
+ if (!event) return; // SDL loops until null; maybe we should do that too. or not.
+
+ unsigned int time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff);
+
+ switch([event type])
+ {
+ case NSMouseMoved:
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ {
+ Ecore_Event_Mouse_Move * ev = calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!ev) return;
+ ev->x = [event locationInWindow].x;
+ ev->y = [event locationInWindow].y;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+ ev->timestamp = time;
+ ev->window = [event window];
+ ev->modifiers = 0; /* FIXME: keep modifier around. */
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
+
+ [NSApp sendEvent:event]; // pass along mouse events, for window manager
+ break;
+ }
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ {
+ Ecore_Event_Mouse_Button * ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!ev) return;
+ ev->x = [event locationInWindow].x;
+ ev->y = [event locationInWindow].y;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+ ev->timestamp = time;
+ ev->buttons = [event buttonNumber] + 1; // Apple indexes buttons from 0
+
+ if ([event clickCount] == 2)
+ ev->double_click = 1;
+ else
+ ev->double_click = 0;
+
+ if ([event clickCount] >= 3)
+ ev->triple_click = 1;
+ else
+ ev->triple_click = 0;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
+
+ [NSApp sendEvent:event]; // pass along mouse events, for window manager
+ break;
+ }
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ {
+ Ecore_Event_Mouse_Button * ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!ev) return;
+ ev->x = [event locationInWindow].x;
+ ev->y = [event locationInWindow].y;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+ ev->timestamp = time;
+ ev->buttons = [event buttonNumber] + 1; // Apple indexes buttons from 0
+
+ if ([event clickCount] == 2)
+ ev->double_click = 1;
+ else
+ ev->double_click = 0;
+
+ if ([event clickCount] >= 3)
+ ev->triple_click = 1;
+ else
+ ev->triple_click = 0;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
+
+ [NSApp sendEvent:event]; // pass along mouse events, for window manager
+ break;
+ }
+ case NSKeyDown:
+ {
+ Ecore_Event_Key *ev;
+ unsigned int i;
+
+ ev = calloc(1, sizeof (Ecore_Event_Key));
+ if (!ev) return;
+ ev->timestamp = time;
+
+ for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i)
+ {
+ if (keystable[i].code == tolower([[event charactersIgnoringModifiers] characterAtIndex:0]))
+ {
+ ev->keyname = keystable[i].name;
+ ev->string = keystable[i].compose;
+
+ ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
+ return;
+ }
+ }
+
+ break;
+ }
+ case NSKeyUp:
+ {
+ Ecore_Event_Key *ev;
+ unsigned int i;
+
+ ev = calloc(1, sizeof (Ecore_Event_Key));
+ if (!ev) return;
+ ev->timestamp = time;
+
+ for (i = 0; i < sizeof (keystable) / sizeof (struct _ecore_cocoa_keys_s); ++i)
+ {
+ if (keystable[i].code == tolower([[event charactersIgnoringModifiers] characterAtIndex:0]))
+ {
+ ev->keyname = keystable[i].name;
+ ev->string = keystable[i].compose;
+
+ ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
+ return;
+ }
+ }
+
+ break;
+ }
+ case NSFlagsChanged:
+ {
+ int flags = [event modifierFlags];
+
+ Ecore_Event_Key *evDown = NULL;
+ Ecore_Event_Key *evUp = NULL;
+
+ evDown = calloc(1, sizeof (Ecore_Event_Key));
+ if (!evDown) return;
+
+ evUp = calloc(1, sizeof (Ecore_Event_Key));
+ if (!evUp)
+ {
+ free(evDown);
+ return;
+ }
+
+ // Turn special key flags on
+ if (flags & NSShiftKeyMask)
+ evDown->keyname = "Shift_L";
+ else if (flags & NSControlKeyMask)
+ evDown->keyname = "Control_L";
+ else if (flags & NSAlternateKeyMask)
+ evDown->keyname = "Alt_L";
+ else if (flags & NSCommandKeyMask)
+ evDown->keyname = "Super_L";
+ else if (flags & NSAlphaShiftKeyMask)
+ evDown->keyname = "Caps_Lock";
+
+ if (evDown->keyname)
+ {
+ evDown->timestamp = time;
+ evDown->string = "";
+ ecore_event_add(ECORE_EVENT_KEY_DOWN, evDown, NULL, NULL);
+ old_flags = flags;
+ break;
+ }
+
+ int changed_flags = flags ^ old_flags;
+
+ // Turn special key flags off
+ if (changed_flags & NSShiftKeyMask)
+ evUp->keyname = "Shift_L";
+ else if (changed_flags & NSControlKeyMask)
+ evUp->keyname = "Control_L";
+ else if (changed_flags & NSAlternateKeyMask)
+ evUp->keyname = "Alt_L";
+ else if (changed_flags & NSCommandKeyMask)
+ evUp->keyname = "Super_L";
+ else if (changed_flags & NSAlphaShiftKeyMask)
+ evUp->keyname = "Caps_Lock";
+
+ if (evUp->keyname)
+ {
+ evUp->timestamp = time;
+ evUp->string = "";
+ ecore_event_add(ECORE_EVENT_KEY_UP, evUp, NULL, NULL);
+ old_flags = flags;
+ break;
+ }
+
+ break;
+ }
+ case NSAppKitDefined:
+ {
+ if ([event subtype] == NSApplicationActivatedEventType)
+ ecore_event_add(ECORE_COCOA_EVENT_GOT_FOCUS, NULL, NULL, NULL);
+ else if ([event subtype] == NSApplicationDeactivatedEventType)
+ ecore_event_add(ECORE_COCOA_EVENT_LOST_FOCUS, NULL, NULL, NULL);
+ [NSApp sendEvent:event]; // pass along AppKit events, for window manager
+ break;
+ }
+ case NSScrollWheel:
+ {
+ break;
+ }
+ default:
+ {
+ [NSApp sendEvent:event];
+ break;
+ }
+ }
+
+ [event release];
+}
--- /dev/null
+#ifndef _ECORE_COCOA_PRIVATE_H\r
+#define _ECORE_COCOA_PRIVATE_H\r
+\r
+\r
+struct _Ecore_Cocoa_Window\r
+{\r
+ NSWindow *window;\r
+\r
+ unsigned int borderless : 1;\r
+};\r
+\r
+\r
+#endif\r
--- /dev/null
+#ifdef HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif\r
+\r
+#include <Cocoa/Cocoa.h>\r
+\r
+#include "Ecore_Cocoa.h"\r
+\r
+Ecore_Cocoa_Window *\r
+ecore_cocoa_window_new(int x,\r
+ int y,\r
+ int width,\r
+ int height)\r
+{\r
+ NSWindow *window;\r
+\r
+ window = [[NSWindow alloc]\r
+ initWithContentRect:NSMakeRect(x, y, width, height)\r
+ styleMask:(NSTitledWindowMask |\r
+ NSClosableWindowMask |\r
+ NSResizableWindowMask |\r
+ NSMiniaturizableWindowMask)\r
+ backing:NSBackingStoreBuffered\r
+ defer:NO\r
+ screen:nil\r
+ ];\r
+ if (!window)\r
+ return NULL;\r
+\r
+ return window;\r
+}\r
+\r
+void\r
+ecore_cocoa_window_free(Ecore_Cocoa_Window *window)\r
+{\r
+ if (!window)\r
+ return;\r
+\r
+ [window release];\r
+}\r
+\r
+void\r
+ecore_cocoa_window_move(Ecore_Cocoa_Window *window,\r
+ int x,\r
+ int y)\r
+{\r
+ if (!window)\r
+ return;\r
+}\r
+\r
+void\r
+ecore_cocoa_window_resize(Ecore_Cocoa_Window *window,\r
+ int width,\r
+ int height)\r
+{\r
+ if (!window)\r
+ return;\r
+\r
+ [window setContentSize: NSMakeSize(width, height)];\r
+}\r
+\r
+void\r
+ecore_cocoa_window_move_resize(Ecore_Cocoa_Window *window,\r
+ int x,\r
+ int y,\r
+ int width,\r
+ int height)\r
+{\r
+ if (!window)\r
+ return;\r
+}\r
+\r
+void\r
+ecore_cocoa_window_title_set(Ecore_Cocoa_Window *window, const char *title)\r
+{\r
+ if (!window || !title)\r
+ return;\r
+\r
+ [window setTitle:[NSString stringWithUTF8String:title]];\r
+}\r
+\r
+void\r
+ecore_cocoa_window_show(Ecore_Cocoa_Window *window)\r
+{\r
+ if (!window || [window isVisible])\r
+ return;\r
+\r
+ [window orderFront:NSApp];\r
+}\r
+\r
+void\r
+ecore_cocoa_window_hide(Ecore_Cocoa_Window *window)\r
+{\r
+ if (!window || ![window isVisible])\r
+ return;\r
+\r
+ [window orderOut:NSApp];\r
+}\r
+\r
+void\r
+ecore_cocoa_window_borderless_set(Ecore_Cocoa_Window *window,\r
+ int on)\r
+{\r
+ if (!window)\r
+ return;\r
+\r
+ if (on)\r
+ [window setContentBorderThickness:0.0\r
+ forEdje:NSMinXEdge | NSMinYEdge | NSMaxXEdge | NSMaxYEdge];\r
+}\r
--- /dev/null
+.deps
+.libs
+Ecore_Con.h
+Makefile
+Makefile.in
+*.lo
+libecore_con.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef _ECORE_CON_H
+#define _ECORE_CON_H
+
+#include <time.h>
+#include <libgen.h>
+#ifdef _WIN32
+# include <ws2tcpip.h>
+#else
+# include <netdb.h>
+#endif
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file Ecore_Con.h
+ * @brief Sockets functions.
+ *
+ * The Ecore Connection Library ( @c Ecore_Con ) provides simple mechanisms
+ * for communications between programs using reliable sockets. It saves
+ * the programmer from having to worry about file descripters and waiting
+ * for incoming connections.
+ *
+ * There are two main objects in the @c Ecore_Con library: the @c
+ * Ecore_Con_Server and the @c Ecore_Con_Client.
+ *
+ * The @c Ecore_Con_Server represents a server that can be connected to.
+ * It is used regardless of whether the program is acting as a server or
+ * client itself.
+ *
+ * To create a listening server, call @c ecore_con_server_add().
+ *
+ * To connect to a server, call @c ecore_con_server_connect(). Data can
+ * then be sent to the server using the @c ecore_con_server_send().
+ *
+ * Whenever a client connection is made to an @c Ecore_Con_Server, a
+ * @c ECORE_CON_CLIENT_ADD event is emitted. Any event callbacks that are
+ * called receive a @c Ecore_Con_Client object, which represents a
+ * connection that that particular client.
+ *
+ * Functions are described in the following groupings:
+ * @li @ref Ecore_Con_Lib_Group
+ * @li @ref Ecore_Con_Server_Group
+ * @li @ref Ecore_Con_Client_Group
+ * @li @ref Ecore_Con_Url_Group
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct _Ecore_Con_Server Ecore_Con_Server; /**< A connection handle */
+ typedef struct _Ecore_Con_Client Ecore_Con_Client; /**< A connection handle */
+ typedef struct _Ecore_Con_Url Ecore_Con_Url;
+ typedef struct _Ecore_Con_Info Ecore_Con_Info;
+
+ typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos);
+
+ typedef enum _Ecore_Con_Type
+ {
+ ECORE_CON_LOCAL_USER = 0,
+ ECORE_CON_LOCAL_SYSTEM = 1,
+ ECORE_CON_LOCAL_ABSTRACT = 2,
+ ECORE_CON_REMOTE_TCP = 3,
+ ECORE_CON_REMOTE_MCAST = 4,
+ ECORE_CON_REMOTE_UDP = 5,
+ ECORE_CON_REMOTE_BROADCAST = 6,
+ ECORE_CON_REMOTE_NODELAY = 7,
+
+ ECORE_CON_USE_SSL2 = (1 << 4),
+ ECORE_CON_USE_SSL3 = (1 << 5),
+ ECORE_CON_USE_TLS = (1 << 6)
+ } Ecore_Con_Type;
+#define ECORE_CON_USE_SSL ECORE_CON_USE_SSL2
+#define ECORE_CON_REMOTE_SYSTEM ECORE_CON_REMOTE_TCP
+
+ typedef enum _Ecore_Con_Url_Time
+ {
+ ECORE_CON_URL_TIME_NONE = 0,
+ ECORE_CON_URL_TIME_IFMODSINCE,
+ ECORE_CON_URL_TIME_IFUNMODSINCE,
+ ECORE_CON_URL_TIME_LASTMOD
+ } Ecore_Con_Url_Time;
+
+ typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add;
+ typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del;
+ typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add;
+ typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del;
+ typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data;
+ typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data;
+ typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data;
+ typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete;
+ typedef struct _Ecore_Con_Event_Url_Progress Ecore_Con_Event_Url_Progress;
+
+ struct _Ecore_Con_Event_Client_Add
+ {
+ Ecore_Con_Client *client;
+ };
+
+ struct _Ecore_Con_Event_Client_Del
+ {
+ Ecore_Con_Client *client;
+ };
+
+ struct _Ecore_Con_Event_Server_Add
+ {
+ Ecore_Con_Server *server;
+ };
+
+ struct _Ecore_Con_Event_Server_Del
+ {
+ Ecore_Con_Server *server;
+ };
+
+ struct _Ecore_Con_Event_Client_Data
+ {
+ Ecore_Con_Client *client;
+ void *data;
+ int size;
+ };
+
+ struct _Ecore_Con_Event_Server_Data
+ {
+ Ecore_Con_Server *server;
+ void *data;
+ int size;
+ };
+
+ struct _Ecore_Con_Event_Url_Data
+ {
+ Ecore_Con_Url *url_con;
+ int size;
+ unsigned char data[1];
+ };
+
+ struct _Ecore_Con_Event_Url_Complete
+ {
+ Ecore_Con_Url *url_con;
+ int status;
+ };
+
+ struct _Ecore_Con_Event_Url_Progress
+ {
+ Ecore_Con_Url *url_con;
+ struct {
+ double total;
+ double now;
+ } down;
+ struct {
+ double total;
+ double now;
+ } up;
+ };
+
+ EAPI extern int ECORE_CON_EVENT_CLIENT_ADD;
+ EAPI extern int ECORE_CON_EVENT_CLIENT_DEL;
+ EAPI extern int ECORE_CON_EVENT_SERVER_ADD;
+ EAPI extern int ECORE_CON_EVENT_SERVER_DEL;
+ EAPI extern int ECORE_CON_EVENT_CLIENT_DATA;
+ EAPI extern int ECORE_CON_EVENT_SERVER_DATA;
+ EAPI extern int ECORE_CON_EVENT_URL_DATA;
+ EAPI extern int ECORE_CON_EVENT_URL_COMPLETE;
+ EAPI extern int ECORE_CON_EVENT_URL_PROGRESS;
+
+ EAPI int ecore_con_init(void);
+ EAPI int ecore_con_shutdown(void);
+
+ EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, const char *name, int port, const void *data);
+
+ EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, const char *name, int port, const void *data);
+ EAPI void *ecore_con_server_del(Ecore_Con_Server *svr);
+ EAPI void *ecore_con_server_data_get(Ecore_Con_Server *svr);
+ EAPI int ecore_con_server_connected_get(Ecore_Con_Server *svr);
+ EAPI Eina_List *ecore_con_server_clients_get(Ecore_Con_Server *svr);
+ EAPI int ecore_con_server_send(Ecore_Con_Server *svr, const void *data, int size);
+ EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients);
+ EAPI char *ecore_con_server_ip_get(Ecore_Con_Server *svr);
+ EAPI void ecore_con_server_flush(Ecore_Con_Server *svr);
+
+ EAPI int ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size);
+ EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl);
+ EAPI void *ecore_con_client_del(Ecore_Con_Client *cl);
+ EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data);
+ EAPI void *ecore_con_client_data_get(Ecore_Con_Client *cl);
+ EAPI char *ecore_con_client_ip_get(Ecore_Con_Client *cl);
+ EAPI void ecore_con_client_flush(Ecore_Con_Client *cl);
+
+ EAPI int ecore_con_ssl_available_get(void);
+
+ EAPI int ecore_con_url_init(void);
+ EAPI int ecore_con_url_shutdown(void);
+ EAPI Ecore_Con_Url *ecore_con_url_new(const char *url);
+ EAPI Ecore_Con_Url *ecore_con_url_custom_new(const char *url, const char *custom_request);
+ EAPI void ecore_con_url_destroy(Ecore_Con_Url *url_con);
+ EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data);
+ EAPI void *ecore_con_url_data_get(Ecore_Con_Url *url_con);
+ EAPI void ecore_con_url_additional_header_add(Ecore_Con_Url *url_con, const char *key, const char *value);
+ EAPI void ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con);
+ EAPI const Eina_List *ecore_con_url_response_headers_get(Ecore_Con_Url *url_con);
+ EAPI int ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url);
+ EAPI void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd);
+ EAPI int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con);
+ EAPI int ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, const char *username, const char *password, Eina_Bool safe);
+ EAPI int ecore_con_url_send(Ecore_Con_Url *url_con, const void *data, size_t length, const char *content_type);
+ EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t tm);
+
+ EAPI int ecore_con_info_get(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data, struct addrinfo *hints);
+
+ EAPI int ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, const char *filename, const char *user, const char *pass, const char *upload_dir);
+ EAPI void ecore_con_url_verbose_set(Ecore_Con_Url *url_con, int verbose);
+ EAPI void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, int use_epsv);
+ EAPI int ecore_con_url_http_post_send(Ecore_Con_Url *url_con, void *curl_httppost);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_con \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
+@SSL_CFLAGS@ \
+@CURL_CFLAGS@ \
+@EINA_CFLAGS@ \
+@TLS_CFLAGS@ \
+@CARES_CFLAGS@ \
+@WIN32_CPPFLAGS@
+
+if BUILD_ECORE_CON
+
+lib_LTLIBRARIES = libecore_con.la
+include_HEADERS = \
+Ecore_Con.h
+
+libecore_con_la_SOURCES = \
+ecore_con.c \
+ecore_con_ssl.c \
+ecore_con_url.c \
+ecore_con_local.c
+
+if HAVE_CARES
+libecore_con_la_SOURCES += ecore_con_ares.c
+else
+libecore_con_la_SOURCES += ecore_con_info.c
+endif
+
+libecore_con_la_CFLAGS = @WIN32_CFLAGS@
+libecore_con_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@SSL_LIBS@ @CURL_LIBS@ @EINA_LIBS@ @TLS_LIBS@ @CARES_LIBS@ @WIN32_LIBS@
+
+libecore_con_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_con_release_info@
+
+endif
+
+EXTRA_DIST = ecore_con_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+
+#ifdef HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Con.h"
+#include "ecore_con_private.h"
+
+static void _ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *info);
+static void _ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *info);
+static void _ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *info);
+static void _ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *info);
+
+static void _ecore_con_server_free(Ecore_Con_Server *svr);
+static void _ecore_con_client_free(Ecore_Con_Client *cl);
+
+static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler);
+
+static void _ecore_con_server_flush(Ecore_Con_Server *svr);
+static void _ecore_con_client_flush(Ecore_Con_Client *cl);
+
+static void _ecore_con_event_client_add_free(void *data, void *ev);
+static void _ecore_con_event_client_del_free(void *data, void *ev);
+static void _ecore_con_event_client_data_free(void *data, void *ev);
+static void _ecore_con_event_server_add_free(void *data, void *ev);
+static void _ecore_con_event_server_del_free(void *data, void *ev);
+static void _ecore_con_event_server_data_free(void *data, void *ev);
+
+EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0;
+EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0;
+EAPI int ECORE_CON_EVENT_SERVER_ADD = 0;
+EAPI int ECORE_CON_EVENT_SERVER_DEL = 0;
+EAPI int ECORE_CON_EVENT_CLIENT_DATA = 0;
+EAPI int ECORE_CON_EVENT_SERVER_DATA = 0;
+
+static Eina_List *servers = NULL;
+static int _ecore_con_init_count = 0;
+int _ecore_con_log_dom = -1;
+
+/**
+ * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions
+ *
+ * Utility functions that set up and shut down the Ecore Connection
+ * library.
+ */
+
+/**
+ * Initialises the Ecore_Con library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_Con_Lib_Group
+ */
+EAPI int
+ecore_con_init(void)
+{
+ if (++_ecore_con_init_count != 1)
+ return _ecore_con_init_count;
+
+#ifdef HAVE_EVIL
+ if (!evil_init())
+ return --_ecore_con_init_count;
+#endif
+
+ if (!ecore_init())
+ return --_ecore_con_init_count;
+
+ _ecore_con_log_dom = eina_log_domain_register("EcoreCon", ECORE_CON_DEFAULT_LOG_COLOR);
+ if(_ecore_con_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for Ecore Con.");
+ ecore_shutdown();
+ return --_ecore_con_init_count;
+ }
+ ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new();
+ ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new();
+ ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new();
+ ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new();
+ ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new();
+ ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new();
+
+ /* TODO Remember return value, if it fails, use gethostbyname() */
+ ecore_con_ssl_init();
+ ecore_con_info_init();
+
+ return _ecore_con_init_count;
+}
+
+/**
+ * Shuts down the Ecore_Con library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_Con_Lib_Group
+ */
+EAPI int
+ecore_con_shutdown(void)
+{
+ if (--_ecore_con_init_count != 0)
+ return _ecore_con_init_count;
+
+ while (servers)
+ _ecore_con_server_free(eina_list_data_get(servers));
+
+ ecore_con_info_shutdown();
+ ecore_con_ssl_shutdown();
+ eina_log_domain_unregister(_ecore_con_log_dom);
+ _ecore_con_log_dom = -1;
+ ecore_shutdown();
+#ifdef HAVE_EVIL
+ evil_shutdown();
+#endif
+
+ return _ecore_con_init_count;
+}
+
+/**
+ * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions
+ *
+ * Functions that operate on Ecore server objects.
+ */
+
+/**
+ * Creates a server to listen for connections.
+ *
+ * The socket on which the server listens depends on the connection
+ * type:
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the server will listen on
+ * the Unix socket "~/.ecore/[name]/[port]".
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen
+ * on Unix socket "/tmp/.ecore_service|[name]|[port]".
+ * @li If @a compl_type is @c ECORE_CON_REMOTE_TCP, the server will listen
+ * on TCP port @c port.
+ *
+ * @param compl_type The connection type.
+ * @param name Name to associate with the socket. It is used when
+ * generating the socket name of a Unix socket. Though
+ * it is not used for the TCP socket, it still needs to
+ * be a valid character array. @c NULL will not be
+ * accepted.
+ * @param port Number to identify socket. When a Unix socket is used,
+ * it becomes part of the socket name. When a TCP socket
+ * is used, it is used as the TCP port.
+ * @param data Data to associate with the created Ecore_Con_Server
+ * object.
+ * @return A new Ecore_Con_Server.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI Ecore_Con_Server *
+ecore_con_server_add(Ecore_Con_Type compl_type, const char *name, int port,
+ const void *data)
+{
+ Ecore_Con_Server *svr;
+ Ecore_Con_Type type;
+
+ if (port < 0 || !name) return NULL;
+ /* local user socket: FILE: ~/.ecore/[name]/[port] */
+ /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
+ /* remote system socket: TCP/IP: [name]:[port] */
+ svr = calloc(1, sizeof(Ecore_Con_Server));
+ if (!svr) return NULL;
+
+ svr->name = strdup(name);
+ if (!svr->name) goto error;
+ svr->type = compl_type;
+ svr->port = port;
+ svr->data = (void *)data;
+ svr->created = 1;
+ svr->reject_excess_clients = 0;
+ svr->client_limit = -1;
+ svr->clients = NULL;
+ svr->ppid = getpid();
+ ecore_con_ssl_server_prepare(svr);
+
+ type = compl_type & ECORE_CON_TYPE;
+
+ if ((type == ECORE_CON_LOCAL_USER) ||
+ (type == ECORE_CON_LOCAL_SYSTEM) ||
+ (type == ECORE_CON_LOCAL_ABSTRACT))
+ {
+ /* Local */
+ if (!ecore_con_local_listen(svr, _ecore_con_svr_handler, svr)) goto error;
+ }
+
+ if ((type == ECORE_CON_REMOTE_TCP) ||
+ (type == ECORE_CON_REMOTE_NODELAY))
+ {
+ /* TCP */
+ if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, svr)) goto error;
+ }
+ else if ((type == ECORE_CON_REMOTE_MCAST) ||
+ (type == ECORE_CON_REMOTE_UDP))
+ {
+ /* UDP and MCAST */
+ if (!ecore_con_info_udp_listen(svr, _ecore_con_cb_udp_listen, svr)) goto error;
+ }
+
+ servers = eina_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
+
+ return svr;
+
+ error:
+ if (svr->name) free(svr->name);
+ if (svr->path) free(svr->path);
+#ifndef _WIN32
+ if (svr->fd >= 0) close(svr->fd);
+ if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
+ if (svr->write_buf) free(svr->write_buf);
+ if (svr->ip) free(svr->ip);
+#endif
+ ecore_con_ssl_server_shutdown(svr);
+ free(svr);
+ return NULL;
+}
+
+/**
+ * Creates a server object to represent the server listening at the
+ * given port.
+ *
+ * The socket to which the server connects depends on the connection type:
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the function will
+ * connect to the server listening on the Unix socket
+ * "~/.ecore/[name]/[port]".
+ * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the function will
+ * connect to the server listening on the Unix socket
+ * "/tmp/.ecore_service|[name]|[port]".
+ * @li If @a compl_type is @c ECORE_CON_REMOTE_TCP, the function will
+ * connect to the server listening on the TCP port "[name]:[port]".
+ *
+ * @param compl_type The connection type.
+ * @param name Name used when determining what socket to connect to.
+ * It is used to generate the socket name when the socket
+ * is a Unix socket. It is used as the hostname when
+ * connecting with a TCP socket.
+ * @param port Number to identify the socket to connect to. Used when
+ * generating the socket name for a Unix socket, or as the
+ * TCP port when connecting to a TCP socket.
+ * @param data Data to associate with the created Ecore_Con_Server
+ * object.
+ * @return A new Ecore_Con_Server.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI Ecore_Con_Server *
+ecore_con_server_connect(Ecore_Con_Type compl_type, const char *name, int port,
+ const void *data)
+{
+ Ecore_Con_Server *svr;
+ Ecore_Con_Type type;
+
+ if (!name) return NULL;
+ /* local user socket: FILE: ~/.ecore/[name]/[port] */
+ /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */
+ /* remote system socket: TCP/IP: [name]:[port] */
+ svr = calloc(1, sizeof(Ecore_Con_Server));
+ if (!svr) return NULL;
+
+ svr->name = strdup(name);
+ if (!svr->name) goto error;
+ svr->type = compl_type;
+ svr->port = port;
+ svr->data = (void *)data;
+ svr->created = 0;
+ svr->reject_excess_clients = 0;
+ svr->clients = NULL;
+ svr->client_limit = -1;
+ ecore_con_ssl_server_prepare(svr);
+
+ type = compl_type & ECORE_CON_TYPE;
+
+ if (((type == ECORE_CON_REMOTE_TCP) ||
+ (type == ECORE_CON_REMOTE_NODELAY) ||
+ (type == ECORE_CON_REMOTE_UDP) ||
+ (type == ECORE_CON_REMOTE_BROADCAST)) &&
+ (port < 0))
+ goto error;
+
+ if ((type == ECORE_CON_LOCAL_USER) ||
+ (type == ECORE_CON_LOCAL_SYSTEM) ||
+ (type == ECORE_CON_LOCAL_ABSTRACT))
+ {
+ /* Local */
+ if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, svr, _ecore_con_event_server_add_free)) goto error;
+ }
+
+ if ((type == ECORE_CON_REMOTE_TCP) ||
+ (type == ECORE_CON_REMOTE_NODELAY))
+ {
+ /* TCP */
+ if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, svr)) goto error;
+ }
+ else if ((type == ECORE_CON_REMOTE_UDP) ||
+ (type == ECORE_CON_REMOTE_BROADCAST))
+ {
+ /* UDP and MCAST */
+ if (!ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, svr)) goto error;
+ }
+
+ servers = eina_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER);
+
+ return svr;
+
+ error:
+ if (svr->name) free(svr->name);
+ if (svr->path) free(svr->path);
+ if (svr->fd >= 0) close(svr->fd);
+ if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
+ ecore_con_ssl_server_shutdown(svr);
+ free(svr);
+ return NULL;
+}
+
+/**
+ * Closes the connection and frees the given server.
+ * @param svr The given server.
+ * @return Data associated with the server when it was created.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI void *
+ecore_con_server_del(Ecore_Con_Server *svr)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del");
+ return NULL;
+ }
+ if (svr->delete_me) return NULL;
+
+ data = svr->data;
+ svr->data = NULL;
+ svr->delete_me = 1;
+ if (svr->event_count > 0)
+ {
+ if (svr->fd_handler)
+ {
+ ecore_main_fd_handler_del(svr->fd_handler);
+ svr->fd_handler = NULL;
+ }
+ }
+ else
+ {
+ _ecore_con_server_free(svr);
+ }
+ return data;
+}
+
+/**
+ * Retrieves the data associated with the given server.
+ * @param svr The given server.
+ * @return The associated data.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI void *
+ecore_con_server_data_get(Ecore_Con_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
+ return NULL;
+ }
+ return svr->data;
+}
+
+/**
+ * Retrieves whether the given server is currently connected.
+ * @todo Check that this function does what the documenter believes it does.
+ * @param svr The given server.
+ * @return @c 1 if the server is connected. @c 0 otherwise.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI int
+ecore_con_server_connected_get(Ecore_Con_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_connected_get");
+ return 0;
+ }
+ if (svr->connecting) return 0;
+ return 1;
+}
+
+/**
+ * Retrieves the current list of clients.
+ * @param svr The given server.
+ * @return The list of clients on this server.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI Eina_List *
+ecore_con_server_clients_get(Ecore_Con_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_clients_get");
+ return NULL;
+ }
+ return svr->clients;
+}
+
+/**
+ * Sends the given data to the given server.
+ * @param svr The given server.
+ * @param data The given data.
+ * @param size Length of the data, in bytes, to send.
+ * @return The number of bytes sent. @c 0 will be returned if there is an
+ * error.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI int
+ecore_con_server_send(Ecore_Con_Server *svr, const void *data, int size)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_send");
+ return 0;
+ }
+ if (svr->dead) return 0;
+ if (!data) return 0;
+ if (size < 1) return 0;
+ if (svr->fd_handler)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
+ if (svr->write_buf)
+ {
+ unsigned char *newbuf;
+
+ newbuf = realloc(svr->write_buf, svr->write_buf_size + size);
+ if (newbuf) svr->write_buf = newbuf;
+ else return 0;
+ memcpy(svr->write_buf + svr->write_buf_size, data, size);
+ svr->write_buf_size += size;
+ }
+ else
+ {
+ svr->write_buf = malloc(size);
+ if (!svr->write_buf) return 0;
+ svr->write_buf_size = size;
+ memcpy(svr->write_buf, data, size);
+ }
+ return size;
+}
+
+/**
+ * Sets a limit on the number of clients that can be handled concurrently
+ * by the given server, and a policy on what to do if excess clients try to
+ * connect.
+ * Beware that if you set this once ecore is already running, you may
+ * already have pending CLIENT_ADD events in your event queue. Those
+ * clients have already connected and will not be affected by this call.
+ * Only clients subsequently trying to connect will be affected.
+ * @param svr The given server.
+ * @param client_limit The maximum number of clients to handle
+ * concurrently. -1 means unlimited (default). 0
+ * effectively disables the server.
+ * @param reject_excess_clients Set to 1 to automatically disconnect
+ * excess clients as soon as they connect if you are
+ * already handling client_limit clients. Set to 0
+ * (default) to just hold off on the "accept()"
+ * system call until the number of active clients
+ * drops. This causes the kernel to queue up to 4096
+ * connections (or your kernel's limit, whichever is
+ * lower).
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI void
+ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_client_limit_set");
+ return;
+ }
+ svr->client_limit = client_limit;
+ svr->reject_excess_clients = reject_excess_clients;
+}
+
+/**
+ * Gets the IP address of a server that has been connected to.
+ *
+ * @param svr The given server.
+ * @return A pointer to an internal string that contains the IP address of
+ * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
+ * This string should not be modified or trusted to stay valid after
+ * deletion for the @p svr object. If no IP is known NULL is returned.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI char *
+ecore_con_server_ip_get(Ecore_Con_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_ip_get");
+ return NULL;
+ }
+ return svr->ip;
+}
+
+/**
+ * Flushes all pending data to the given server. Will return when done.
+ *
+ * @param svr The given server.
+ * @ingroup Ecore_Con_Server_Group
+ */
+EAPI void
+ecore_con_server_flush(Ecore_Con_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_flush");
+ return;
+ }
+ _ecore_con_server_flush(svr);
+}
+
+/**
+ * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions
+ *
+ * Functions that operate on Ecore connection client objects.
+ */
+
+/**
+ * Sends the given data to the given client.
+ * @param cl The given client.
+ * @param data The given data.
+ * @param size Length of the data, in bytes, to send.
+ * @return The number of bytes sent. @c 0 will be returned if there is an
+ * error.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI int
+ecore_con_client_send(Ecore_Con_Client *cl, const void *data, int size)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_send");
+ return 0;
+ }
+ if (cl->dead) return 0;
+ if (!data) return 0;
+ if (size < 1) return 0;
+ if (cl->fd_handler)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
+
+ if(cl->server && cl->server->type == ECORE_CON_REMOTE_UDP)
+ {
+ sendto(cl->server->fd, data, size, 0, (struct sockaddr *) cl->client_addr, cl->client_addr_len);
+ }
+ else if (cl->buf)
+ {
+ unsigned char *newbuf;
+
+ newbuf = realloc(cl->buf, cl->buf_size + size);
+ if (newbuf) cl->buf = newbuf;
+ else return 0;
+ memcpy(cl->buf + cl->buf_size, data, size);
+ cl->buf_size += size;
+ }
+ else
+ {
+ cl->buf = malloc(size);
+ if (!cl->buf) return 0;
+ cl->buf_size = size;
+ memcpy(cl->buf, data, size);
+ }
+ return size;
+}
+
+/**
+ * Retrieves the server representing the socket the client has
+ * connected to.
+ * @param cl The given client.
+ * @return The server that the client connected to.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI Ecore_Con_Server *
+ecore_con_client_server_get(Ecore_Con_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_server_get");
+ return NULL;
+ }
+ return cl->server;
+}
+
+/**
+ * Closes the connection and frees memory allocated to the given client.
+ * @param cl The given client.
+ * @return Data associated with the client.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI void *
+ecore_con_client_del(Ecore_Con_Client *cl)
+{
+ void *data = NULL;
+
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
+ return NULL;
+ }
+
+ if(cl->client_addr && cl->server && (cl->server->type == ECORE_CON_REMOTE_UDP ||
+ cl->server->type == ECORE_CON_REMOTE_MCAST))
+ free(cl->client_addr);
+
+ data = cl->data;
+
+ cl->data = NULL;
+ cl->delete_me = 1;
+ if (cl->event_count > 0)
+ {
+ if (cl->fd_handler)
+ {
+ ecore_main_fd_handler_del(cl->fd_handler);
+ cl->fd_handler = NULL;
+ }
+ }
+ else
+ {
+ if (cl->server)
+ cl->server->clients = eina_list_remove(cl->server->clients, cl);
+ _ecore_con_client_free(cl);
+ }
+ return data;
+}
+
+/**
+ * Sets the data associated with the given client to @p data.
+ * @param cl The given client.
+ * @param data What to set the data to.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI void
+ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_set");
+ return;
+ }
+ cl->data = (void *)data;
+}
+
+/**
+ * Retrieves the data associated with the given client.
+ * @param cl The given client.
+ * @return The data associated with @p cl.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI void *
+ecore_con_client_data_get(Ecore_Con_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_get");
+ return NULL;
+ }
+ return cl->data;
+}
+
+/**
+ * Gets the IP address of a cleint that has connected.
+ *
+ * @param cl The given client.
+ * @return A pointer to an internal string that contains the IP address of
+ * the connected client in the form "XXX.YYY.ZZZ.AAA" IP notation.
+ * This string should not be modified or trusted to stay valid after
+ * deletion for the @p cl object. If no IP is known NULL is returned.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI char *
+ecore_con_client_ip_get(Ecore_Con_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_ip_get");
+ return NULL;
+ }
+ return cl->ip;
+}
+
+/**
+ * Flushes all pending data to the given client. Will return when done.
+ *
+ * @param cl The given client.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI void
+ecore_con_client_flush(Ecore_Con_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_flush");
+ return;
+ }
+ _ecore_con_client_flush(cl);
+}
+
+static void
+_ecore_con_server_free(Ecore_Con_Server *svr)
+{
+ Ecore_Con_Client *cl;
+ double t_start, t;
+
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
+ t_start = ecore_time_get();
+ while ((svr->write_buf) && (!svr->dead))
+ {
+ _ecore_con_server_flush(svr);
+ t = ecore_time_get();
+ if ((t - t_start) > 0.5)
+ {
+ WRN("ECORE_CON: EEK - stuck in _ecore_con_server_free() trying\n"
+ " to flush data out from the server, and have been for\n"
+ " %1.1f seconds. This is taking too long. Aborting flush.",
+ (t - t_start));
+ break;
+ }
+ }
+ if (svr->write_buf) free(svr->write_buf);
+ EINA_LIST_FREE(svr->clients, cl)
+ _ecore_con_client_free(cl);
+ if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
+ unlink(svr->path);
+ if (svr->fd >= 0) close(svr->fd);
+ ecore_con_ssl_server_shutdown(svr);
+ if (svr->name) free(svr->name);
+ if (svr->path) free(svr->path);
+ if (svr->ip) free(svr->ip);
+ if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
+ servers = eina_list_remove(servers, svr);
+ free(svr);
+}
+
+static void
+_ecore_con_client_free(Ecore_Con_Client *cl)
+{
+ double t_start, t;
+
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
+ t_start = ecore_time_get();
+ while ((cl->buf) && (!cl->dead))
+ {
+ _ecore_con_client_flush(cl);
+ t = ecore_time_get();
+ if ((t - t_start) > 0.5)
+ {
+ WRN("EEK - stuck in _ecore_con_client_free() trying\n"
+ " to flush data out from the client, and have been for\n"
+ " %1.1f seconds. This is taking too long. Aborting flush.",
+ (t - t_start));
+ break;
+ }
+ }
+ if (cl->buf) free(cl->buf);
+ if (cl->fd >= 0) close(cl->fd);
+ if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
+ if (cl->ip) free(cl->ip);
+ free(cl);
+}
+
+static void
+kill_server(Ecore_Con_Server *svr)
+{
+ if (!svr->delete_me)
+ {
+ Ecore_Con_Event_Server_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Del));
+ if (e)
+ {
+ svr->event_count++;
+ e->server = svr;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e,
+ _ecore_con_event_server_del_free, NULL);
+ }
+ }
+
+ svr->dead = 1;
+ if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler);
+ svr->fd_handler = NULL;
+}
+
+static void
+_ecore_con_cb_tcp_listen(void *data, Ecore_Con_Info *net_info)
+{
+ Ecore_Con_Server *svr;
+ struct linger lin;
+
+ svr = data;
+
+ if(!net_info) goto error;
+
+ svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+ if (svr->fd < 0) goto error;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+ lin.l_onoff = 1;
+ lin.l_linger = 0;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin, sizeof(struct linger)) < 0) goto error;
+ if (svr->type == ECORE_CON_REMOTE_NODELAY)
+ {
+ int flag = 1;
+
+ if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) < 0)
+ goto error;
+ }
+ if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) goto error;
+ if (listen(svr->fd, 4096) < 0) goto error;
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+ _ecore_con_svr_handler, svr, NULL, NULL);
+ if (!svr->fd_handler) goto error;
+
+ return;
+
+ error:
+ ecore_con_ssl_server_shutdown(svr);
+ kill_server(svr);
+}
+
+static void
+_ecore_con_cb_udp_listen(void *data, Ecore_Con_Info *net_info)
+{
+ Ecore_Con_Server *svr;
+ Ecore_Con_Type type;
+ struct ip_mreq mreq;
+ struct ipv6_mreq mreq6;
+ const int on = 1;
+
+ svr = data;
+ type = svr->type;
+ type &= ECORE_CON_TYPE;
+
+ if (!net_info) goto error;
+
+ svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+ if(svr->fd < 0) goto error;
+
+ if (type == ECORE_CON_REMOTE_MCAST)
+ {
+ if (net_info->info.ai_family == AF_INET)
+ {
+ if (!inet_pton(net_info->info.ai_family, net_info->ip, &mreq.imr_multiaddr)) goto error;
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq,sizeof(mreq)) != 0) goto error;
+ }
+ else if (net_info->info.ai_family == AF_INET6)
+ {
+ if (!inet_pton(net_info->info.ai_family, net_info->ip, &mreq6.ipv6mr_multiaddr)) goto error;
+ mreq6.ipv6mr_interface = htonl(INADDR_ANY);
+ if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq6,sizeof(mreq6)) != 0) goto error;
+ }
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0) goto error;
+ }
+
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+ if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) goto error;
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+ _ecore_con_svr_udp_handler, svr, NULL, NULL);
+ if (!svr->fd_handler) goto error;
+ svr->ip = strdup(net_info->ip);
+
+ return;
+
+ error:
+ ecore_con_ssl_server_shutdown(svr);
+ kill_server(svr);
+}
+
+static void
+_ecore_con_cb_tcp_connect(void *data, Ecore_Con_Info *net_info)
+{
+ Ecore_Con_Server *svr;
+ int res;
+ int curstate = 0;
+
+ svr = data;
+
+ if (!net_info) goto error;
+ svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+ if (svr->fd < 0) goto error;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0)
+ goto error;
+ if (svr->type == ECORE_CON_REMOTE_NODELAY)
+ {
+ int flag = 1;
+
+ if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) < 0)
+ goto error;
+ }
+ res = connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen);
+#ifdef _WIN32
+ if (res == SOCKET_ERROR)
+ {
+ if (WSAGetLastError() != WSAEINPROGRESS)
+ goto error;
+#else
+ if (res < 0)
+ {
+ if (errno != EINPROGRESS)
+ goto error;
+#endif
+ svr->connecting = 1;
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
+ _ecore_con_cl_handler, svr, NULL, NULL);
+ }
+ else
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+ _ecore_con_cl_handler, svr, NULL, NULL);
+
+ if (svr->type & ECORE_CON_SSL)
+ if (ecore_con_ssl_server_init(svr))
+ goto error;
+
+ if (!svr->fd_handler) goto error;
+ svr->ip = strdup(net_info->ip);
+
+ return;
+
+ error:
+ ecore_con_ssl_server_shutdown(svr);
+ kill_server(svr);
+}
+
+static void
+_ecore_con_cb_udp_connect(void *data, Ecore_Con_Info *net_info)
+{
+ Ecore_Con_Server *svr;
+ int curstate = 0;
+ int broadcast = 1;
+ svr = data;
+
+ if (!net_info) goto error;
+ svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, net_info->info.ai_protocol);
+ if (svr->fd < 0) goto error;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
+
+ if(svr->type == ECORE_CON_REMOTE_BROADCAST)
+ {
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST, (const void *)&broadcast, sizeof(broadcast)) < 0) goto error;
+ }
+ else
+ {
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0) goto error;
+ }
+
+ if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
+ goto error;
+ else
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
+ _ecore_con_cl_udp_handler, svr, NULL, NULL);
+ if (!svr->fd_handler) goto error;
+ svr->ip = strdup(net_info->ip);
+
+ return;
+
+ error:
+ ecore_con_ssl_server_shutdown(svr);
+ kill_server(svr);
+}
+
+static Ecore_Con_State
+svr_try_connect_plain(Ecore_Con_Server *svr)
+{
+ int res;
+ int so_err = 0;
+ unsigned int size = sizeof(int);
+
+ res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size);
+#ifdef _WIN32
+ if (res == SOCKET_ERROR)
+ so_err = -1;
+
+ if (so_err == WSAEINPROGRESS && !svr->dead)
+ return ECORE_CON_INPROGRESS;
+#else
+ if (res < 0)
+ so_err = -1;
+
+ if (so_err == EINPROGRESS && !svr->dead)
+ return ECORE_CON_INPROGRESS;
+#endif
+
+ if (so_err != 0)
+ {
+ /* we lost our server! */
+ kill_server(svr);
+ return ECORE_CON_DISCONNECTED;
+ }
+ else
+ {
+ if (!svr->delete_me)
+ {
+ /* we got our server! */
+ Ecore_Con_Event_Server_Add *e;
+
+ svr->connecting = 0;
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
+ if (e)
+ {
+ svr->event_count++;
+ e->server = svr;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
+ _ecore_con_event_server_add_free, NULL);
+ }
+ }
+ if (svr->fd_handler)
+ {
+ if (!svr->write_buf)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ }
+ }
+
+ if (!svr->dead)
+ return ECORE_CON_CONNECTED;
+ else
+ return ECORE_CON_DISCONNECTED;
+}
+
+/* returns 1 on success, 0 on failure */
+static Ecore_Con_State svr_try_connect(Ecore_Con_Server *svr)
+{
+ if (!(svr->type & ECORE_CON_SSL))
+ return svr_try_connect_plain(svr);
+ else
+ {
+ switch (ecore_con_ssl_server_try(svr)) {
+ case ECORE_CON_CONNECTED:
+ return svr_try_connect_plain(svr);
+ case ECORE_CON_DISCONNECTED:
+ kill_server(svr);
+ return ECORE_CON_DISCONNECTED;
+ default:
+ return ECORE_CON_INPROGRESS;
+ }
+ }
+}
+
+static char *
+_ecore_con_pretty_ip(struct sockaddr *client_addr, socklen_t size)
+{
+ char ipbuf[INET6_ADDRSTRLEN + 1];
+
+ /* show v4mapped address in pretty form */
+ if (client_addr->sa_family == AF_INET6)
+ {
+ struct sockaddr_in6 *sa6;
+
+ sa6 = (struct sockaddr_in6 *) client_addr;
+ if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
+ {
+ snprintf(ipbuf, sizeof (ipbuf), "%u.%u.%u.%u",
+ sa6->sin6_addr.s6_addr[12],
+ sa6->sin6_addr.s6_addr[13],
+ sa6->sin6_addr.s6_addr[14],
+ sa6->sin6_addr.s6_addr[15]);
+ return strdup(ipbuf);
+ }
+ }
+
+ if (getnameinfo(client_addr, size,
+ ipbuf, sizeof (ipbuf), NULL, 0, NI_NUMERICHOST))
+ return strdup("0.0.0.0");
+
+ ipbuf[sizeof (ipbuf) - 1] = 0;
+ return strdup(ipbuf);
+}
+
+static int
+_ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Ecore_Con_Server *svr;
+ int new_fd;
+ unsigned char incoming[256];
+ size_t size_in;
+
+ svr = data;
+ if (svr->dead) return 1;
+ if (svr->delete_me) return 1;
+ if ((svr->client_limit >= 0) && (!svr->reject_excess_clients))
+ {
+ if (eina_list_count(svr->clients) >= (unsigned int)svr->client_limit)
+ return 1;
+ }
+ /* a new client */
+ size_in = sizeof(incoming);
+
+ memset(&incoming, 0, size_in);
+ new_fd = accept(svr->fd, (struct sockaddr *)&incoming, (socklen_t *)&size_in);
+ if (new_fd >= 0)
+ {
+ Ecore_Con_Client *cl;
+
+ if ((svr->client_limit >= 0) && (svr->reject_excess_clients))
+ {
+ if (eina_list_count(svr->clients) >= (unsigned int)svr->client_limit)
+ {
+ close(new_fd);
+ return 1;
+ }
+ }
+
+ cl = calloc(1, sizeof(Ecore_Con_Client));
+ if (!cl)
+ {
+ close(new_fd);
+ return 1;
+ }
+
+ fcntl(new_fd, F_SETFL, O_NONBLOCK);
+ fcntl(new_fd, F_SETFD, FD_CLOEXEC);
+ cl->fd = new_fd;
+ cl->server = svr;
+
+ if ((svr->type & ECORE_CON_SSL) &&
+ (ecore_con_ssl_client_init(cl)))
+ {
+ close(new_fd);
+ ecore_con_ssl_client_shutdown(cl);
+ return 1;
+ }
+
+ cl->fd_handler =
+ ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
+ _ecore_con_svr_cl_handler, cl, NULL, NULL);
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
+ svr->clients = eina_list_append(svr->clients, cl);
+ if (!svr->path)
+ cl->ip = _ecore_con_pretty_ip((struct sockaddr *) &incoming, size_in);
+ if (!cl->delete_me)
+ {
+ Ecore_Con_Event_Client_Add *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
+ if (e)
+ {
+ cl->event_count++;
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e,
+ _ecore_con_event_client_add_free, NULL);
+ }
+ }
+ }
+ return 1;
+}
+
+static int
+_ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ Ecore_Con_Server *svr;
+
+ svr = data;
+ if (svr->dead) return 1;
+ if (svr->delete_me) return 1;
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ {
+ unsigned char *inbuf = NULL;
+ int inbuf_num = 0;
+
+ if (svr->connecting && (svr_try_connect(svr) != ECORE_CON_CONNECTED))
+ return 1;
+
+ for (;;)
+ {
+ int num;
+ int lost_server = 1;
+ unsigned char buf[READBUFSIZ];
+
+ if (!(svr->type & ECORE_CON_SSL))
+ {
+ if (((num = read(svr->fd, buf, READBUFSIZ)) < 0) &&
+ (errno == EAGAIN))
+ lost_server = 0;
+ }
+ else
+ if (!(num = ecore_con_ssl_server_read(svr, buf, READBUFSIZ)))
+ lost_server = 0;
+
+ if (num < 1)
+ {
+ if (inbuf && !svr->delete_me)
+ {
+ Ecore_Con_Event_Server_Data *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
+ if (e)
+ {
+ svr->event_count++;
+ e->server = svr;
+ e->data = inbuf;
+ e->size = inbuf_num;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
+ _ecore_con_event_server_data_free,
+ NULL);
+ }
+ }
+ if (lost_server) kill_server(svr);
+ break;
+ }
+
+ inbuf = realloc(inbuf, inbuf_num + num);
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
+ }
+
+/* #if USE_OPENSSL */
+/* if (svr->fd_handler) */
+/* { */
+/* if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ) */
+/* ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); */
+/* else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE) */
+/* ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); */
+/* } */
+/* #endif */
+ }
+ else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+ {
+ if (svr->connecting && !svr_try_connect (svr))
+ return 1;
+ _ecore_con_server_flush(svr);
+ }
+
+ return 1;
+}
+
+static int
+_ecore_con_cl_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ Ecore_Con_Server *svr;
+
+ svr = data;
+ if (svr->dead) return 1;
+ if (svr->delete_me) return 1;
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ {
+ unsigned char buf[65536];
+ int num = 0;
+
+ errno = 0;
+ num = read(svr->fd, buf, 65536);
+ if (num > 0)
+ {
+ if (!svr->delete_me)
+ {
+ Ecore_Con_Event_Server_Data *e;
+ unsigned char *inbuf;
+
+ inbuf = malloc(num);
+ if(inbuf == NULL)
+ return 1;
+ memcpy(inbuf, buf, num);
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Data));
+ if (e)
+ {
+ svr->event_count++;
+ e->server = svr;
+ e->data = inbuf;
+ e->size = num;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
+ _ecore_con_event_server_data_free,
+ NULL);
+ }
+ }
+ }
+ }
+ else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+ _ecore_con_server_flush(svr);
+
+ return 1;
+}
+
+static int
+_ecore_con_svr_udp_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ Ecore_Con_Server *svr;
+ Ecore_Con_Client *cl = NULL;
+
+ svr = data;
+ if (svr->dead) return 1;
+ if (svr->delete_me) return 1;
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ {
+ unsigned char buf[READBUFSIZ];
+ unsigned char client_addr[256];
+ unsigned int client_addr_len = sizeof(client_addr);
+ int num;
+
+ errno = 0;
+#ifdef _WIN32
+ num = fcntl(svr->fd, F_SETFL, O_NONBLOCK);
+ if (num >= 0)
+ num = recvfrom(svr->fd, buf, sizeof(buf), 0, (struct sockaddr*) &client_addr, &client_addr_len);
+#else
+ num = recvfrom(svr->fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*) &client_addr, &client_addr_len);
+#endif
+
+ if (num > 0)
+ {
+ if (!svr->delete_me)
+ {
+ Ecore_Con_Event_Client_Data *e;
+ unsigned char *inbuf;
+
+ /* Create a new client for use in the client data event */
+ cl = calloc(1, sizeof(Ecore_Con_Client));
+ if(cl == NULL)
+ return 1;
+ cl->buf = NULL;
+ cl->fd = 0;
+ cl->fd_handler = NULL;
+ cl->server = svr;
+ cl->client_addr = calloc(1, client_addr_len);
+ cl->client_addr_len = client_addr_len;
+ if(cl->client_addr == NULL)
+ {
+ free(cl);
+ return 1;
+ }
+ memcpy(cl->client_addr, &client_addr, client_addr_len);
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
+ svr->clients = eina_list_append(svr->clients, cl);
+
+ cl->ip = _ecore_con_pretty_ip(cl->client_addr, cl->client_addr_len);
+
+ inbuf = malloc(num);
+ if(inbuf == NULL)
+ {
+ free(cl->client_addr);
+ free(cl);
+ return 1;
+ }
+
+ memcpy(inbuf, buf, num);
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
+ if (e)
+ {
+ svr->event_count++;
+ e->client = cl;
+ e->data = inbuf;
+ e->size = num;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
+ _ecore_con_event_client_data_free,
+ NULL);
+ }
+
+ if(!cl->delete_me)
+ {
+ Ecore_Con_Event_Client_Add *add;
+
+ add = calloc(1, sizeof(Ecore_Con_Event_Client_Add));
+ if(add)
+ {
+ /*cl->event_count++;*/
+ add->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, add,
+ _ecore_con_event_client_add_free, NULL);
+ }
+ }
+ }
+ if ((errno == EIO) || (errno == EBADF) ||
+ (errno == EPIPE) || (errno == EINVAL) ||
+ (errno == ENOSPC) || (num == 0)/* is num == 0 right? */)
+ {
+ if (!svr->delete_me)
+ {
+ /* we lost our client! */
+ Ecore_Con_Event_Client_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
+ if (e)
+ {
+ svr->event_count++;
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
+ _ecore_con_event_client_del_free,
+ NULL);
+ }
+ }
+ svr->dead = 1;
+ if (svr->fd_handler)
+ ecore_main_fd_handler_del(svr->fd_handler);
+ svr->fd_handler = NULL;
+ }
+ }
+ }
+ else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+ _ecore_con_client_flush(cl);
+ return 1;
+}
+
+static int
+_ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ Ecore_Con_Client *cl;
+
+ cl = data;
+ if (cl->dead) return 1;
+ if (cl->delete_me) return 1;
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ {
+ unsigned char *inbuf = NULL;
+ int inbuf_num = 0;
+ int lost_client = 1;
+
+ for (;;)
+ {
+ unsigned char buf[65536];
+ int num;
+
+ errno = 0;
+
+ if (!(cl->server->type & ECORE_CON_SSL))
+ {
+ if (((num = read(cl->fd, buf, 65536)) < 0) &&
+ (errno == EAGAIN))
+ lost_client = 0;
+ }
+ else
+ if (!(num = ecore_con_ssl_client_read(cl, buf, 65536)))
+ lost_client = 0;
+
+ if (num < 1)
+ {
+ if (inbuf && !cl->delete_me)
+ {
+ Ecore_Con_Event_Client_Data *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Data));
+ if (e)
+ {
+ cl->event_count++;
+ e->client = cl;
+ e->data = inbuf;
+ e->size = inbuf_num;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
+ _ecore_con_event_client_data_free,
+ NULL);
+ }
+ }
+
+ if (lost_client)
+ {
+ if (!cl->delete_me)
+ {
+ /* we lost our client! */
+ Ecore_Con_Event_Client_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
+ if (e)
+ {
+ cl->event_count++;
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
+ _ecore_con_event_client_del_free,
+ NULL);
+ }
+ }
+ cl->dead = 1;
+ if (cl->fd_handler)
+ ecore_main_fd_handler_del(cl->fd_handler);
+ cl->fd_handler = NULL;
+ }
+ break;
+ }
+ else
+ {
+ inbuf = realloc(inbuf, inbuf_num + num);
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
+ }
+ }
+ }
+ else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+ _ecore_con_client_flush(cl);
+ return 1;
+}
+
+static void
+_ecore_con_server_flush(Ecore_Con_Server *svr)
+{
+ int count, num;
+
+ if (!svr->write_buf) return;
+
+ /* check whether we need to write anything at all.
+ * we must not write zero bytes with SSL_write() since it
+ * causes undefined behaviour
+ */
+ if (svr->write_buf_size == svr->write_buf_offset)
+ return;
+
+ num = svr->write_buf_size - svr->write_buf_offset;
+
+ if (!(svr->type & ECORE_CON_SSL))
+ count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num);
+ else
+ count = ecore_con_ssl_server_write(svr, svr->write_buf + svr->write_buf_offset, num);
+
+ if (count < 0)
+ {
+ /* we lost our server! */
+ kill_server(svr);
+ return;
+ }
+
+ svr->write_buf_offset += count;
+ if (svr->write_buf_offset >= svr->write_buf_size)
+ {
+ svr->write_buf_size = 0;
+ svr->write_buf_offset = 0;
+ free(svr->write_buf);
+ svr->write_buf = NULL;
+ if (svr->fd_handler)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ }
+}
+
+static void
+_ecore_con_client_flush(Ecore_Con_Client *cl)
+{
+ int count, num;
+
+ if (!cl->buf) return;
+ num = cl->buf_size - cl->buf_offset;
+ if (!(cl->server->type & ECORE_CON_SSL))
+ count = write(cl->fd, cl->buf + cl->buf_offset, num);
+ else
+ count = ecore_con_ssl_client_write(cl, cl->buf + cl->buf_offset, num);
+ if (count < 1)
+ {
+ if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) ||
+ (errno == EINVAL) || (errno == ENOSPC))
+ {
+ if (!cl->delete_me)
+ {
+ /* we lost our client! */
+ Ecore_Con_Event_Client_Del *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Client_Del));
+ if (e)
+ {
+ cl->event_count++;
+ e->client = cl;
+ ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e,
+ _ecore_con_event_client_del_free, NULL);
+ }
+ cl->dead = 1;
+ if (cl->fd_handler)
+ ecore_main_fd_handler_del(cl->fd_handler);
+ cl->fd_handler = NULL;
+ }
+ }
+ return;
+ }
+ cl->buf_offset += count;
+ if (cl->buf_offset >= cl->buf_size)
+ {
+ cl->buf_size = 0;
+ cl->buf_offset = 0;
+ free(cl->buf);
+ cl->buf = NULL;
+ if (cl->fd_handler)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
+ }
+}
+
+static void
+_ecore_con_event_client_add_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Add *e;
+
+ e = ev;
+ e->client->event_count--;
+ if ((e->client->event_count == 0) && (e->client->delete_me))
+ ecore_con_client_del(e->client);
+ free(e);
+}
+
+static void
+_ecore_con_event_client_del_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Del *e;
+
+ e = ev;
+ e->client->event_count--;
+ if ((e->client->event_count == 0) && (e->client->delete_me))
+ ecore_con_client_del(e->client);
+ free(e);
+}
+
+static void
+_ecore_con_event_client_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Data *e;
+
+ e = ev;
+ e->client->event_count--;
+ if (e->data) free(e->data);
+ if (((e->client->event_count == 0) && (e->client->delete_me)) ||
+ ((e->client->server && (e->client->server->type == ECORE_CON_REMOTE_UDP ||
+ e->client->server->type == ECORE_CON_REMOTE_MCAST))))
+ ecore_con_client_del(e->client);
+ free(e);
+}
+
+static void
+_ecore_con_event_server_add_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Add *e;
+
+ e = ev;
+ e->server->event_count--;
+ if ((e->server->event_count == 0) && (e->server->delete_me))
+ _ecore_con_server_free(e->server);
+ free(e);
+}
+
+static void
+_ecore_con_event_server_del_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Del *e;
+
+ e = ev;
+ e->server->event_count--;
+ if ((e->server->event_count == 0) && (e->server->delete_me))
+ _ecore_con_server_free(e->server);
+ free(e);
+}
+
+static void
+_ecore_con_event_server_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Data *e;
+
+ e = ev;
+ e->server->event_count--;
+ if (e->data) free(e->data);
+ if ((e->server->event_count == 0) && (e->server->delete_me))
+ _ecore_con_server_free(e->server);
+ free(e);
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/*
+ * This version of ecore_con_info use c-ares to provide asynchronous dns lookup.
+ *
+ * Note: It doesn't fork nor does it use libc getaddrinfo.
+ * http://c-ares.haxx.se/docs.html
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <ares.h>
+
+#include "Ecore.h"
+#include "Ecore_Con.h"
+#include "ecore_con_private.h"
+
+typedef struct _Ecore_Con_FD Ecore_Con_FD;
+typedef struct _Ecore_Con_CAres Ecore_Con_CAres;
+
+struct _Ecore_Con_FD
+{
+ Ecore_Fd_Handler *handler;
+ int active;
+ int fd;
+};
+
+struct _Ecore_Con_CAres
+{
+ Ecore_Con_Server *svr;
+ Ecore_Con_Info_Cb done_cb;
+ void *data;
+ struct addrinfo hints;
+ Ecore_Con_Info *result;
+
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ } addr;
+
+ Eina_Bool byaddr;
+};
+
+static ares_channel info_channel;
+static int info_init = 0;
+static Eina_List *info_fds = NULL;
+static int active = 0;
+static Ecore_Timer *tm = NULL;
+static fd_set info_readers, info_writers;
+
+static void _ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg, int status, int timeouts, char *node, char *service);
+static void _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, int status, int timeouts, struct hostent *hostent);
+static int _ecore_con_info_cares_fd_cb(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_info_cares_timeout_cb(void *data);
+static void _ecore_con_info_cares_clean(void);
+
+int
+ecore_con_info_init(void)
+{
+ if (info_init == 0)
+ {
+ if (ares_library_init(ARES_LIB_INIT_ALL) != 0)
+ return 0;
+ if (ares_init(&info_channel) != ARES_SUCCESS)
+ {
+ ares_library_cleanup();
+ return 0;
+ }
+ }
+
+ info_init++;
+ return info_init;
+}
+
+int
+ecore_con_info_shutdown(void)
+{
+ info_init--;
+ if (info_init == 0)
+ {
+ /* Cancel all ongoing request */
+ ares_cancel(info_channel);
+ ares_destroy(info_channel);
+
+ /* Destroy FD handler here. */
+ /* Shutdown ares */
+ ares_library_cleanup();
+ }
+ return info_init;
+}
+
+int
+ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_udp_connect(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_udp_listen(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+EAPI int
+ecore_con_info_get(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data,
+ struct addrinfo *hints)
+{
+ Ecore_Con_CAres *cares;
+ int ai_family = AF_UNSPEC;
+
+ cares = calloc(1, sizeof (Ecore_Con_CAres));
+ if (!cares) return 0;
+
+ cares->svr = svr;
+ cares->done_cb = done_cb;
+ cares->data = data;
+
+ if (hints)
+ {
+ ai_family = hints->ai_family;
+ memcpy(&cares->hints, hints, sizeof (struct addrinfo));
+ }
+
+ if (inet_pton(AF_INET, svr->name, &cares->addr.v4) == 1)
+ {
+ cares->byaddr = EINA_TRUE;
+ ares_gethostbyaddr(info_channel, &cares->addr.v4, sizeof (cares->addr.v4), AF_INET, (ares_host_callback) _ecore_con_info_ares_host_cb, cares);
+ }
+ else if (inet_pton(AF_INET6, svr->name, &cares->addr.v6) == 1)
+ {
+ cares->byaddr = EINA_TRUE;
+ ares_gethostbyaddr(info_channel, &cares->addr.v6, sizeof (cares->addr.v6), AF_INET6, (ares_host_callback) _ecore_con_info_ares_host_cb, cares);
+ }
+ else
+ {
+ cares->byaddr = EINA_FALSE;
+ ares_gethostbyname(info_channel, svr->name, ai_family, (ares_host_callback) _ecore_con_info_ares_host_cb, cares);
+ }
+
+ _ecore_con_info_cares_clean();
+
+ return 1;
+}
+
+static int
+_ecore_con_info_fds_search(const Ecore_Con_FD *fd1, const Ecore_Con_FD *fd2)
+{
+ return fd1->fd - fd2->fd;
+}
+
+static Eina_Bool
+_ecore_con_info_fds_lookup(int fd)
+{
+ Ecore_Con_FD fdl;
+ Ecore_Con_FD *search;
+
+ fdl.fd = fd;
+
+ search = eina_list_search_unsorted(info_fds, (Eina_Compare_Cb) _ecore_con_info_fds_search, &fdl);
+
+ if (search)
+ {
+ search->active = active;
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
+static void
+_ecore_con_info_cares_clean(void)
+{
+ fd_set readers, writers;
+ Eina_List *l, *l_next;
+ Ecore_Con_FD *ecf;
+ int nfds;
+ int i;
+
+ FD_ZERO(&readers);
+ FD_ZERO(&writers);
+ nfds = ares_fds(info_channel, &readers, &writers);
+
+ active++;
+ for (i = 0; i < nfds; ++i)
+ {
+ int flags = 0;
+
+ if (FD_ISSET(i, &readers)) flags |= ECORE_FD_READ;
+ if (FD_ISSET(i, &writers)) flags |= ECORE_FD_WRITE;
+
+ if (flags)
+ {
+ if (!_ecore_con_info_fds_lookup(i))
+ {
+ ecf = malloc(sizeof (Ecore_Con_FD));
+ if (ecf)
+ {
+ ecf->fd = i;
+ ecf->active = active;
+ ecf->handler = ecore_main_fd_handler_add(i, ECORE_FD_WRITE | ECORE_FD_READ,
+ _ecore_con_info_cares_fd_cb,
+ NULL, NULL, NULL);
+ info_fds = eina_list_append(info_fds, ecf);
+ }
+ }
+ }
+ }
+
+ info_readers = readers;
+ info_writers = writers;
+
+ EINA_LIST_FOREACH_SAFE(info_fds, l, l_next, ecf)
+ {
+ if (ecf->active != active)
+ {
+ ecore_main_fd_handler_del(ecf->handler);
+ free(ecf);
+ info_fds = eina_list_remove_list(info_fds, l);
+ }
+ }
+
+ if (!info_fds)
+ {
+ if (tm) ecore_timer_del(tm);
+ tm = NULL;
+ }
+ else
+ {
+ struct timeval tv;
+
+ ares_timeout(info_channel, NULL, &tv);
+
+ if (tm)
+ ecore_timer_delay(tm, tv.tv_sec);
+ else
+ tm = ecore_timer_add((double) tv.tv_sec, _ecore_con_info_cares_timeout_cb, NULL);
+ }
+}
+
+static int
+_ecore_con_info_cares_timeout_cb(void *data)
+{
+ ares_process(info_channel, &info_readers, &info_writers);
+ _ecore_con_info_cares_clean();
+
+ return 1;
+}
+
+static int
+_ecore_con_info_cares_fd_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ ares_process(info_channel, &info_readers, &info_writers);
+ _ecore_con_info_cares_clean();
+
+ return 1;
+}
+
+static void
+_ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, int status, int timeouts, struct hostent *hostent)
+{
+ struct sockaddr *addr;
+ int addrlen;
+ int length = 0;
+
+ /* Found something ? */
+ switch (status)
+ {
+ case ARES_SUCCESS:
+ if (hostent->h_addr_list[0] == NULL)
+ {
+ fprintf(stderr, "No IP found\n");
+ goto on_error;
+ }
+
+ switch (hostent->h_addrtype)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *addri;
+
+ addrlen = sizeof (struct sockaddr_in);
+ addri = malloc(addrlen);
+
+ if (!addri)
+ {
+ fprintf(stderr, "Not enough memory\n");
+ goto on_error;
+ }
+
+ addri->sin_family = AF_INET;
+ addri->sin_port = htons(arg->svr->port);
+
+ memcpy(&addri->sin_addr.s_addr, arg->byaddr ? &arg->addr.v4 : (struct in_addr*)hostent->h_addr_list[0], sizeof (struct in_addr));
+
+ addr = (struct sockaddr*) addri;
+ break;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *addri6;
+
+ addrlen = sizeof (struct sockaddr_in6);
+ addri6 = malloc(addrlen);
+
+ if (!addri6)
+ {
+ fprintf(stderr, "Not enough memory\n");
+ goto on_error;
+ }
+
+ addri6->sin6_family = AF_INET6;
+ addri6->sin6_port = htons(arg->svr->port);
+ addri6->sin6_flowinfo = 0;
+ addri6->sin6_scope_id = 0;
+
+ memcpy(&addri6->sin6_addr.s6_addr, arg->byaddr ? &arg->addr.v6 : (struct in6_addr*)hostent->h_addr_list[0], sizeof (struct in6_addr));
+
+ addr = (struct sockaddr*) addri6;
+ break;
+ }
+ default:
+ fprintf(stderr, "Unknown addrtype %i\n", hostent->h_addrtype);
+ goto on_error;
+ }
+
+ if (hostent->h_name)
+ length = strlen(hostent->h_name) + 1;
+
+ arg->result = malloc(sizeof (Ecore_Con_Info) + length);
+ if (!arg->result)
+ {
+ fprintf(stderr, "Not enough memory\n");
+ free(addr);
+ goto on_error;
+ }
+
+ /* FIXME: What to do when hint is not set ? */
+ arg->result->info.ai_flags = arg->hints.ai_flags;
+ arg->result->info.ai_socktype = arg->hints.ai_socktype;
+ arg->result->info.ai_protocol = arg->hints.ai_protocol;
+
+ arg->result->info.ai_family = hostent->h_addrtype;
+ arg->result->info.ai_addrlen = addrlen;
+ arg->result->info.ai_addr = addr;
+ arg->result->info.ai_canonname = (char*) (arg->result + 1);
+
+ strcpy(arg->result->info.ai_canonname, hostent->h_name);
+
+ arg->result->info.ai_next = NULL;
+
+ ares_getnameinfo(info_channel, addr, addrlen,
+ ARES_NI_NUMERICSERV | ARES_NI_NUMERICHOST | ARES_NI_LOOKUPSERVICE | ARES_NI_LOOKUPHOST,
+ (ares_nameinfo_callback) _ecore_con_info_ares_nameinfo, arg);
+ break;
+ case ARES_ENOTIMP: /* unknown family */
+ case ARES_EBADNAME: /* not a valid internet address */
+ case ARES_ENOTFOUND: /* address notfound */
+ case ARES_ENOMEM: /* not enough memory */
+ case ARES_EDESTRUCTION: /* request canceled, shuting down */
+ goto on_error;
+ default:
+ fprintf(stderr, "Unknown status returned by c-ares: %i assuming error\n", status);
+ goto on_error;
+ }
+
+ return ;
+
+ on_error:
+ arg->done_cb(arg->data, NULL);
+ free(arg);
+}
+
+static void
+_ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg, int status, int timeouts, char *node, char *service)
+{
+ switch (status)
+ {
+ case ARES_SUCCESS:
+ if (node) strcpy(arg->result->ip, node);
+ else *arg->result->ip = '\0';
+ if (service) strcpy(arg->result->service, service);
+ else *arg->result->service = '\0';
+
+ arg->done_cb(arg->data, arg->result);
+ break;
+ case ARES_ENOTIMP:
+ case ARES_ENOTFOUND:
+ case ARES_ENOMEM:
+ case ARES_EDESTRUCTION:
+ case ARES_EBADFLAGS:
+ arg->done_cb(arg->data, NULL);
+ break;
+ }
+
+ free(arg->result->info.ai_addr);
+ free(arg->result);
+ free(arg);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * getaddrinfo with callback
+ *
+ * man getaddrinfo
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif defined __GNUC__
+# define alloca __builtin_alloca
+#elif defined _AIX
+# define alloca __alloca
+#elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+#else
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <ctype.h>
+#ifdef __OpenBSD__
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_con_private.h"
+
+typedef struct _CB_Data CB_Data;
+
+struct _CB_Data
+{
+ EINA_INLIST;
+ Ecore_Con_Info_Cb cb_done;
+ void *data;
+ Ecore_Fd_Handler *fdh;
+ pid_t pid;
+ Ecore_Event_Handler *handler;
+ int fd2;
+};
+
+
+static void _ecore_con_info_readdata(CB_Data *cbdata);
+static void _ecore_con_info_slave_free(CB_Data *cbdata);
+static int _ecore_con_info_data_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_info_exit_handler(void *data, int type __UNUSED__, void *event);
+
+static int info_init = 0;
+static CB_Data *info_slaves = NULL;
+
+int
+ecore_con_info_init(void)
+{
+ info_init++;
+ return info_init;
+}
+
+int
+ecore_con_info_shutdown(void)
+{
+ info_init--;
+ if (info_init == 0)
+ {
+ while (info_slaves) _ecore_con_info_slave_free(info_slaves);
+ }
+ return info_init;
+}
+
+int
+ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_udp_connect(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_udp_listen(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+int
+ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data)
+{
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ hints.ai_addr = NULL;
+
+ return ecore_con_info_get(svr, done_cb, data, &hints);
+}
+
+EAPI int
+ecore_con_info_get(Ecore_Con_Server *svr,
+ Ecore_Con_Info_Cb done_cb,
+ void *data,
+ struct addrinfo *hints)
+{
+ CB_Data *cbdata;
+ int fd[2];
+
+ if (pipe(fd) < 0) return 0;
+ cbdata = calloc(1, sizeof(CB_Data));
+ if (!cbdata)
+ {
+ close(fd[0]);
+ close(fd[1]);
+ return 0;
+ }
+ cbdata->cb_done = done_cb;
+ cbdata->data = data;
+ cbdata->fd2 = fd[1];
+ if (!(cbdata->fdh = ecore_main_fd_handler_add(fd[0], ECORE_FD_READ,
+ _ecore_con_info_data_handler,
+ cbdata,
+ NULL, NULL)))
+ {
+ free(cbdata);
+ close(fd[0]);
+ close(fd[1]);
+ return 0;
+ }
+
+ if ((cbdata->pid = fork()) == 0)
+ {
+ Ecore_Con_Info *container;
+ struct addrinfo *result = NULL;
+ char service[NI_MAXSERV];
+ char hbuf[NI_MAXHOST];
+ char sbuf[NI_MAXSERV];
+ void *tosend = NULL;
+ int tosend_len;
+ int canonname_len = 0;
+ int err;
+
+ eina_convert_itoa(svr->port, service);
+ /* CHILD */
+ if (!getaddrinfo(svr->name, service, hints, &result) && result)
+ {
+ if (result->ai_canonname)
+ canonname_len = strlen(result->ai_canonname) + 1;
+ tosend_len = sizeof(Ecore_Con_Info) + result->ai_addrlen + canonname_len;
+
+ if (!(tosend = alloca(tosend_len)))
+ goto on_error;
+
+ container = (Ecore_Con_Info *)tosend;
+
+ container->size = tosend_len;
+
+ memcpy(&container->info, result, sizeof(struct addrinfo));
+ memcpy((char *)tosend + sizeof(Ecore_Con_Info), result->ai_addr, result->ai_addrlen);
+ memcpy((char *)tosend + sizeof(Ecore_Con_Info) + result->ai_addrlen, result->ai_canonname, canonname_len);
+
+ if (!getnameinfo(result->ai_addr, result->ai_addrlen,
+ hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
+ NI_NUMERICHOST | NI_NUMERICSERV))
+ {
+ memcpy(container->ip, hbuf, sizeof(container->ip));
+ memcpy(container->service, sbuf, sizeof(container->service));
+ }
+ err = write(fd[1], tosend, tosend_len);
+ }
+
+on_error:
+ if (result)
+ freeaddrinfo(result);
+ err = write(fd[1], "", 1);
+ close(fd[1]);
+# ifdef __USE_ISOC99
+ _Exit(0);
+# else
+ _exit(0);
+# endif
+ }
+ /* PARENT */
+ cbdata->handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _ecore_con_info_exit_handler, cbdata);
+ close(fd[1]);
+ if (!cbdata->handler)
+ {
+ ecore_main_fd_handler_del(cbdata->fdh);
+ free(cbdata);
+ close(fd[0]);
+ return 0;
+ }
+ info_slaves = (CB_Data *) eina_inlist_append(EINA_INLIST_GET(info_slaves), EINA_INLIST_GET(cbdata));
+ return 1;
+}
+
+static void
+_ecore_con_info_readdata(CB_Data *cbdata)
+{
+ Ecore_Con_Info container;
+ Ecore_Con_Info *recv;
+ void *torecv;
+ int torecv_len;
+
+ ssize_t size;
+
+ size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), &container,
+ sizeof(Ecore_Con_Info));
+ if (size == sizeof(Ecore_Con_Info))
+ {
+ torecv_len = container.size;
+ torecv = malloc(torecv_len);
+
+ memcpy(torecv, &container, sizeof(Ecore_Con_Info));
+
+ size = read(ecore_main_fd_handler_fd_get(cbdata->fdh), (char *)torecv + sizeof(Ecore_Con_Info),
+ torecv_len - sizeof(Ecore_Con_Info));
+ if ((size > 0) && ((size_t)size == torecv_len - sizeof(Ecore_Con_Info)))
+ {
+ recv = (Ecore_Con_Info *)torecv;
+
+ recv->info.ai_addr = (struct sockaddr *)((char *)torecv + sizeof(Ecore_Con_Info));
+ if ((size_t)torecv_len != (sizeof(Ecore_Con_Info) + recv->info.ai_addrlen))
+ recv->info.ai_canonname = (char *)torecv + sizeof(Ecore_Con_Info) + recv->info.ai_addrlen;
+ else
+ recv->info.ai_canonname = NULL;
+ recv->info.ai_next = NULL;
+
+ cbdata->cb_done(cbdata->data, recv);
+
+ free(torecv);
+ }
+ else
+ cbdata->cb_done(cbdata->data, NULL);
+ }
+ else
+ cbdata->cb_done(cbdata->data, NULL);
+ cbdata->cb_done = NULL;
+}
+
+static void
+_ecore_con_info_slave_free(CB_Data *cbdata)
+{
+ info_slaves = (CB_Data *) eina_inlist_remove(EINA_INLIST_GET(info_slaves), EINA_INLIST_GET(cbdata));
+ close(ecore_main_fd_handler_fd_get(cbdata->fdh));
+ ecore_main_fd_handler_del(cbdata->fdh);
+ ecore_event_handler_del(cbdata->handler);
+ free(cbdata);
+}
+
+static int
+_ecore_con_info_data_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ CB_Data *cbdata;
+
+ cbdata = data;
+ if (cbdata->cb_done)
+ {
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ _ecore_con_info_readdata(cbdata);
+ else
+ {
+ cbdata->cb_done(cbdata->data, NULL);
+ cbdata->cb_done = NULL;
+ }
+ }
+ _ecore_con_info_slave_free(cbdata);
+ return 0;
+}
+
+static int
+_ecore_con_info_exit_handler(void *data, int type __UNUSED__, void *event)
+{
+ CB_Data *cbdata;
+ Ecore_Exe_Event_Del *ev;
+
+ ev = event;
+ cbdata = data;
+ if (cbdata->pid != ev->pid) return 1;
+ return 0;
+ _ecore_con_info_slave_free(cbdata);
+ return 0;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+
+#ifdef HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <Ecore.h>
+#include <ecore_private.h>
+
+#include "Ecore_Con.h"
+#include "ecore_con_private.h"
+
+
+#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
+#define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
+
+
+static int _ecore_con_local_init_count = 0;
+
+int
+ecore_con_local_init(void)
+{
+ if (++_ecore_con_local_init_count != 1)
+ return _ecore_con_local_init_count;
+
+ return _ecore_con_local_init_count;
+}
+
+int
+ecore_con_local_shutdown(void)
+{
+ if (--_ecore_con_local_init_count != 0)
+ return _ecore_con_local_init_count;
+
+ return _ecore_con_local_init_count;
+}
+
+int
+ecore_con_local_connect(Ecore_Con_Server *svr,
+ int (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
+ void *data __UNUSED__,
+ void (*cb_free)(void *data, void *ev))
+{
+ char buf[4096];
+ struct sockaddr_un socket_unix;
+ int curstate = 0;
+ const char *homedir;
+ int socket_unix_len;
+
+ if (svr->type == ECORE_CON_LOCAL_USER)
+ {
+ homedir = getenv("HOME");
+ if (!homedir) homedir = getenv("TMP");
+ if (!homedir) homedir = "/tmp";
+ snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, svr->name, svr->port);
+ }
+ else if (svr->type == ECORE_CON_LOCAL_SYSTEM)
+ {
+ if (svr->port < 0)
+ {
+ if (svr->name[0] == '/')
+ strncpy(buf, svr->name, sizeof(buf));
+ else
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", svr->name);
+ }
+ else
+ {
+ if (svr->name[0] == '/')
+ snprintf(buf, sizeof(buf), "%s|%i", svr->name, svr->port);
+ else
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", svr->name, svr->port);
+ }
+ }
+ else if (svr->type == ECORE_CON_LOCAL_ABSTRACT)
+ strncpy(buf, svr->name, sizeof(buf));
+
+ svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (svr->fd < 0) return 0;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) return 0;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) return 0;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0) return 0;
+ socket_unix.sun_family = AF_UNIX;
+
+ if (svr->type == ECORE_CON_LOCAL_ABSTRACT)
+ {
+#ifdef HAVE_ABSTRACT_SOCKETS
+ /* copy name insto sun_path, prefixed by null to indicate abstract namespace */
+ snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", svr->name);
+ socket_unix.sun_path[0] = '\0';
+ socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, svr->name);
+#else
+ WRN("Your system does not support abstract sockets!");
+ return 0;
+#endif
+ }
+ else
+ {
+ strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
+ socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
+ }
+
+ if (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
+ return 0;
+ svr->path = strdup(buf);
+ if (!svr->path) return 0;
+
+ if (svr->type & ECORE_CON_SSL)
+ ecore_con_ssl_server_init(svr);
+
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+ cb_done, svr, NULL, NULL);
+ if (!svr->fd_handler) return 0;
+
+ if (!svr->delete_me)
+ {
+ /* we got our server! */
+ Ecore_Con_Event_Server_Add *e;
+
+ e = calloc(1, sizeof(Ecore_Con_Event_Server_Add));
+ if (e)
+ {
+ svr->event_count++;
+ e->server = svr;
+ ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e,
+ cb_free, NULL);
+ }
+ }
+
+ return 1;
+}
+
+int
+ecore_con_local_listen(Ecore_Con_Server *svr,
+ int (*cb_listen)(void *data, Ecore_Fd_Handler *fd_handler),
+ void *data __UNUSED__)
+{
+ char buf[4096];
+ struct sockaddr_un socket_unix;
+ struct linger lin;
+ mode_t pmode;
+ const char *homedir;
+ struct stat st;
+ mode_t mask;
+ int socket_unix_len;
+
+ mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
+
+ if (svr->type == ECORE_CON_LOCAL_USER)
+ {
+ homedir = getenv("HOME");
+ if (!homedir) homedir = getenv("TMP");
+ if (!homedir) homedir = "/tmp";
+ mask = S_IRUSR | S_IWUSR | S_IXUSR;
+ snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
+ if (stat(buf, &st) < 0) mkdir(buf, mask);
+ snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
+ if (stat(buf, &st) < 0) mkdir(buf, mask);
+ snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, svr->name, svr->port);
+ mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
+ }
+ else if (svr->type == ECORE_CON_LOCAL_SYSTEM)
+ {
+ mask = 0;
+ if (svr->name[0] == '/')
+ {
+ if (svr->port >= 0)
+ snprintf(buf, sizeof(buf), "%s|%i", svr->name, svr->port);
+ else
+ snprintf(buf, sizeof(buf), "%s", svr->name);
+ }
+ else
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", svr->name, svr->port);
+ }
+ else if (svr->type == ECORE_CON_LOCAL_ABSTRACT)
+ strncpy(buf, svr->name, sizeof(buf));
+ pmode = umask(mask);
+ start:
+ svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (svr->fd < 0) goto error_umask;
+ if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error_umask;
+ if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error_umask;
+ lin.l_onoff = 1;
+ lin.l_linger = 0;
+ if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin, sizeof(struct linger)) < 0) goto error_umask;
+ socket_unix.sun_family = AF_UNIX;
+ if (svr->type == ECORE_CON_LOCAL_ABSTRACT)
+ {
+#ifdef HAVE_ABSTRACT_SOCKETS
+ /* . is a placeholder */
+ snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", svr->name);
+ /* first char null indicates abstract namespace */
+ socket_unix.sun_path[0] = '\0';
+ socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, svr->name);
+#else
+ ERR("Your system does not support abstract sockets!");
+ goto error_umask;
+#endif
+ }
+ else
+ {
+ strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
+ socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
+ }
+ if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
+ {
+ if (((svr->type == ECORE_CON_LOCAL_USER) || (svr->type == ECORE_CON_LOCAL_SYSTEM)) &&
+ (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) &&
+ (unlink(buf) >= 0))
+ goto start;
+ else
+ goto error_umask;
+ }
+ if (listen(svr->fd, 4096) < 0) goto error_umask;
+ svr->path = strdup(buf);
+ if (!svr->path) goto error_umask;
+ svr->fd_handler =
+ ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
+ cb_listen, svr, NULL, NULL);
+ umask(pmode);
+ if (!svr->fd_handler) goto error;
+
+ return 1;
+
+ error_umask:
+ umask(pmode);
+ error:
+ return 0;
+}
--- /dev/null
+#ifndef _ECORE_CON_PRIVATE_H
+#define _ECORE_CON_PRIVATE_H
+
+#include "ecore_private.h"
+#include "Ecore_Con.h"
+
+#define ECORE_MAGIC_CON_SERVER 0x77665544
+#define ECORE_MAGIC_CON_CLIENT 0x77556677
+#define ECORE_MAGIC_CON_URL 0x77074255
+
+#define ECORE_CON_TYPE 0x0f
+#define ECORE_CON_SSL 0xf0
+
+#if USE_GNUTLS
+# include <gnutls/gnutls.h>
+#elif USE_OPENSSL
+# include <openssl/ssl.h>
+#endif
+#ifdef HAVE_CURL
+#include <curl/curl.h>
+#endif
+
+#define READBUFSIZ 65536
+
+extern int _ecore_con_log_dom ;
+
+#ifdef ECORE_CON_DEFAULT_LOG_COLOR
+#undef ECORE_LOG_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_CON_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_con_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_con_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_con_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_con_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_con_log_dom, __VA_ARGS__)
+
+typedef enum _Ecore_Con_State
+ {
+ ECORE_CON_CONNECTED,
+ ECORE_CON_DISCONNECTED,
+ ECORE_CON_INPROGRESS
+ } Ecore_Con_State;
+
+typedef enum _Ecore_Con_Ssl_Error
+ {
+ ECORE_CON_SSL_ERROR_NONE = 0,
+ ECORE_CON_SSL_ERROR_NOT_SUPPORTED,
+ ECORE_CON_SSL_ERROR_INIT_FAILED,
+ ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED,
+ ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED
+ } Ecore_Con_Ssl_Error;
+
+struct _Ecore_Con_Client
+{
+ ECORE_MAGIC;
+ int fd;
+ Ecore_Con_Server *server;
+ void *data;
+ Ecore_Fd_Handler *fd_handler;
+ int buf_size;
+ int buf_offset;
+ unsigned char *buf;
+ char *ip;
+ int event_count;
+ struct sockaddr *client_addr;
+ int client_addr_len;
+#if USE_GNUTLS
+ gnutls_session session;
+#elif USE_OPENSSL
+ SSL_CTX *ssl_ctx;
+ SSL *ssl;
+ int ssl_err;
+#endif
+ char dead : 1;
+ char delete_me : 1;
+};
+
+struct _Ecore_Con_Server
+{
+ ECORE_MAGIC;
+ int fd;
+ Ecore_Con_Type type;
+ char *name;
+ int port;
+ char *path;
+ void *data;
+ Ecore_Fd_Handler *fd_handler;
+ Eina_List *clients;
+ int write_buf_size;
+ int write_buf_offset;
+ unsigned char *write_buf;
+ int event_count;
+ int client_limit;
+ pid_t ppid;
+#if USE_GNUTLS
+ gnutls_session session;
+ gnutls_anon_client_credentials_t anoncred_c;
+ gnutls_anon_server_credentials_t anoncred_s;
+#elif USE_OPENSSL
+ SSL_CTX *ssl_ctx;
+ SSL *ssl;
+ int ssl_err;
+#endif
+ char *ip;
+ char dead : 1;
+ char created : 1;
+ char connecting : 1;
+ char reject_excess_clients : 1;
+ char delete_me : 1;
+};
+
+#ifdef HAVE_CURL
+struct _Ecore_Con_Url
+{
+ ECORE_MAGIC;
+ CURL *curl_easy;
+ struct curl_slist *headers;
+ struct curl_httppost* post;
+ Eina_List *additional_headers;
+ Eina_List *response_headers;
+ char *url;
+
+ Ecore_Con_Url_Time condition;
+ time_t time;
+ void *data;
+
+ Ecore_Fd_Handler *fd_handler;
+ int fd;
+ int flags;
+
+ int received;
+ int write_fd;
+
+ unsigned char active : 1;
+};
+#endif
+
+struct _Ecore_Con_Info
+{
+ unsigned int size;
+ struct addrinfo info;
+ char ip[NI_MAXHOST];
+ char service[NI_MAXSERV];
+};
+
+/* from ecore_local.c */
+int ecore_con_local_init(void);
+int ecore_con_local_shutdown(void);
+int ecore_con_local_connect(Ecore_Con_Server *svr, int (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler), void *data, void (*cb_free)(void *data, void *ev));
+int ecore_con_local_listen(Ecore_Con_Server *svr, int (*cb_listen)(void *data, Ecore_Fd_Handler *fd_handler), void *data);
+/* from ecore_con_info.c */
+int ecore_con_info_init(void);
+int ecore_con_info_shutdown(void);
+int ecore_con_info_tcp_connect(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
+int ecore_con_info_tcp_listen(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
+int ecore_con_info_udp_connect(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
+int ecore_con_info_udp_listen(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
+int ecore_con_info_mcast_listen(Ecore_Con_Server *svr, Ecore_Con_Info_Cb done_cb, void *data);
+/* from ecore_con_ssl.c */
+Ecore_Con_Ssl_Error ecore_con_ssl_init(void);
+Ecore_Con_Ssl_Error ecore_con_ssl_shutdown(void);
+void ecore_con_ssl_server_prepare(Ecore_Con_Server *svr);
+Ecore_Con_Ssl_Error ecore_con_ssl_server_init(Ecore_Con_Server *svr);
+Ecore_Con_Ssl_Error ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr);
+Ecore_Con_State ecore_con_ssl_server_try(Ecore_Con_Server *svr);
+int ecore_con_ssl_server_read(Ecore_Con_Server *svr, unsigned char *buf, int size);
+int ecore_con_ssl_server_write(Ecore_Con_Server *svr, unsigned char *buf, int size);
+Ecore_Con_Ssl_Error ecore_con_ssl_client_init(Ecore_Con_Client *svr);
+Ecore_Con_Ssl_Error ecore_con_ssl_client_shutdown(Ecore_Con_Client *svr);
+Ecore_Con_State ecore_con_ssl_client_try(Ecore_Con_Client *svr);
+int ecore_con_ssl_client_read(Ecore_Con_Client *svr, unsigned char *buf, int size);
+int ecore_con_ssl_client_write(Ecore_Con_Client *svr, unsigned char *buf, int size);
+
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if USE_GNUTLS
+# include <gnutls/gnutls.h>
+#elif USE_OPENSSL
+# include <openssl/ssl.h>
+#endif
+
+#ifdef HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_con_private.h"
+
+static int _init_con_ssl_init_count = 0;
+
+#if USE_GNUTLS
+static int _client_connected = 0;
+
+# define SSL_SUFFIX(ssl_func) ssl_func##_gnutls
+# define _ECORE_CON_SSL_AVAILABLE 1
+
+#elif USE_OPENSSL
+# define SSL_SUFFIX(ssl_func) ssl_func##_openssl
+# define _ECORE_CON_SSL_AVAILABLE 2
+
+#else
+# define SSL_SUFFIX(ssl_func) ssl_func##_none
+# define _ECORE_CON_SSL_AVAILABLE 0
+
+#endif
+
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_init)(void);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_shutdown)(void);
+
+static void
+SSL_SUFFIX(_ecore_con_ssl_server_prepare)(Ecore_Con_Server *svr);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_server_init)(Ecore_Con_Server *svr);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(Ecore_Con_Server *svr);
+static Ecore_Con_State
+SSL_SUFFIX(_ecore_con_ssl_server_try)(Ecore_Con_Server *svr);
+static int
+SSL_SUFFIX(_ecore_con_ssl_server_read)(Ecore_Con_Server *svr, unsigned char *buf, int size);
+static int
+SSL_SUFFIX(_ecore_con_ssl_server_write)(Ecore_Con_Server *svr, unsigned char *buf, int size);
+
+static void
+SSL_SUFFIX(_ecore_con_ssl_client_prepare)(Ecore_Con_Client *cl);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_client_init)(Ecore_Con_Client *cl);
+static Ecore_Con_Ssl_Error
+SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(Ecore_Con_Client *cl);
+static int
+SSL_SUFFIX(_ecore_con_ssl_client_read)(Ecore_Con_Client *cl, unsigned char *buf, int size);
+static int
+SSL_SUFFIX(_ecore_con_ssl_client_write)(Ecore_Con_Client *cl, unsigned char *buf, int size);
+
+/*
+ * General SSL API
+ */
+
+Ecore_Con_Ssl_Error
+ecore_con_ssl_init(void)
+{
+ if (!_init_con_ssl_init_count++)
+ SSL_SUFFIX(_ecore_con_ssl_init)();
+
+ return _init_con_ssl_init_count;
+}
+
+Ecore_Con_Ssl_Error
+ecore_con_ssl_shutdown(void)
+{
+ if (!--_init_con_ssl_init_count)
+ SSL_SUFFIX(_ecore_con_ssl_shutdown)();
+
+ return _init_con_ssl_init_count;
+}
+
+/**
+ * Returns if SSL support is available
+ * @return 1 if SSL is available, 0 if it is not.
+ * @ingroup Ecore_Con_Client_Group
+ */
+int
+ecore_con_ssl_available_get(void)
+{
+ return _ECORE_CON_SSL_AVAILABLE;
+}
+
+
+void
+ecore_con_ssl_server_prepare(Ecore_Con_Server *svr)
+{
+ SSL_SUFFIX(_ecore_con_ssl_server_prepare)(svr);
+}
+
+Ecore_Con_Ssl_Error
+ecore_con_ssl_server_init(Ecore_Con_Server *svr)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_init)(svr);
+}
+
+Ecore_Con_Ssl_Error
+ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_shutdown)(svr);
+}
+
+Ecore_Con_State
+ecore_con_ssl_server_try(Ecore_Con_Server *svr)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_try)(svr);
+}
+
+int
+ecore_con_ssl_server_read(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_read)(svr, buf, size);
+}
+
+int
+ecore_con_ssl_server_write(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_server_write)(svr, buf, size);
+}
+
+Ecore_Con_Ssl_Error
+ecore_con_ssl_client_init(Ecore_Con_Client *cl)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_init)(cl);
+}
+
+Ecore_Con_Ssl_Error
+ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_shutdown)(cl);
+}
+
+int
+ecore_con_ssl_client_read(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_read)(cl, buf, size);
+}
+
+int
+ecore_con_ssl_client_write(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ return SSL_SUFFIX(_ecore_con_ssl_client_write)(cl, buf, size);
+}
+
+#if USE_GNUTLS
+
+/*
+ * GnuTLS
+ */
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_init_gnutls(void)
+{
+ if (gnutls_global_init())
+ return ECORE_CON_SSL_ERROR_INIT_FAILED;
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_shutdown_gnutls(void)
+{
+ gnutls_global_deinit();
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static void
+_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr)
+{
+ svr->session = NULL;
+ svr->anoncred_c = NULL;
+ return;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
+{
+ const int *proto = NULL;
+ int ret;
+ const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
+ const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
+ const int tls_proto[] = {
+ GNUTLS_TLS1_0,
+ GNUTLS_TLS1_1,
+#ifdef USE_GNUTLS2
+ GNUTLS_TLS1_2,
+#endif
+ 0
+ };
+
+ switch (svr->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2: /* not supported because of security issues */
+ return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
+ case ECORE_CON_USE_SSL3:
+ proto = ssl3_proto;
+ break;
+ case ECORE_CON_USE_TLS:
+ proto = tls_proto;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+
+ gnutls_anon_allocate_client_credentials(&(svr->anoncred_c));
+ gnutls_init(&(svr->session), GNUTLS_CLIENT);
+ gnutls_set_default_priority(svr->session);
+ gnutls_kx_set_priority(svr->session, kx);
+ gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c);
+ gnutls_kx_set_priority(svr->session, kx);
+ gnutls_protocol_set_priority(svr->session, proto);
+ gnutls_dh_set_prime_bits(svr->session, 512);
+
+ gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)svr->fd);
+
+ while ((ret = gnutls_handshake(svr->session)) < 0)
+ {
+ if ((ret == GNUTLS_E_AGAIN) ||
+ (ret == GNUTLS_E_INTERRUPTED))
+ continue;
+
+ _ecore_con_ssl_server_shutdown_gnutls(svr);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_shutdown_gnutls(Ecore_Con_Server *svr)
+{
+ if (svr->session)
+ {
+ gnutls_bye(svr->session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(svr->session);
+ }
+ if (svr->anoncred_c)
+ gnutls_anon_free_client_credentials(svr->anoncred_c);
+ _ecore_con_ssl_server_prepare_gnutls(svr);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+/* Tries to connect an Ecore_Con_Server to an SSL host.
+ * Returns 1 on success, -1 on fatal errors and 0 if the caller
+ * should try again later.
+ */
+static Ecore_Con_State
+_ecore_con_ssl_server_try_gnutls(Ecore_Con_Server *svr __UNUSED__)
+{
+ return ECORE_CON_CONNECTED;
+}
+
+static int
+_ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_recv(svr->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+static int
+_ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_send(svr->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+static void
+_ecore_con_ssl_client_prepare_gnutls(Ecore_Con_Client *cl)
+{
+ cl->session = NULL;
+ if (!_client_connected)
+ cl->server->anoncred_s = NULL;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
+{
+ const int *proto = NULL;
+ gnutls_dh_params_t dh_params;
+ int ret;
+ const int kx[] = { GNUTLS_KX_ANON_DH, 0 };
+ const int ssl3_proto[] = { GNUTLS_SSL3, 0 };
+ const int tls_proto[] = {
+ GNUTLS_TLS1_0,
+ GNUTLS_TLS1_1,
+#ifdef USE_GNUTLS2
+ GNUTLS_TLS1_2,
+#endif
+ 0
+ };
+
+ switch (cl->server->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2: /* not supported because of security issues */
+ return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;
+ case ECORE_CON_USE_SSL3:
+ proto = ssl3_proto;
+ break;
+ case ECORE_CON_USE_TLS:
+ proto = tls_proto;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+
+ _client_connected++;
+ if (!cl->server->anoncred_s)
+ {
+ gnutls_anon_allocate_server_credentials(&(cl->server->anoncred_s));
+ gnutls_dh_params_init(&dh_params);
+ gnutls_dh_params_generate2(dh_params, 512);
+ gnutls_anon_set_server_dh_params(cl->server->anoncred_s, dh_params);
+ }
+
+ gnutls_init(&(cl->session), GNUTLS_SERVER);
+ gnutls_set_default_priority(cl->session);
+ gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->server->anoncred_s);
+
+ gnutls_kx_set_priority(cl->session, kx);
+
+ gnutls_protocol_set_priority(cl->session, proto);
+
+ gnutls_dh_set_prime_bits(cl->session, 512);
+
+ gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)cl->fd);
+
+ while ((ret = gnutls_handshake(cl->session)) < 0)
+ {
+ if ((ret == GNUTLS_E_AGAIN) ||
+ (ret == GNUTLS_E_INTERRUPTED))
+ continue;
+
+ _ecore_con_ssl_client_shutdown_gnutls(cl);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_shutdown_gnutls(Ecore_Con_Client *cl)
+{
+ if (cl->session)
+ {
+ gnutls_bye(cl->session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(cl->session);
+ }
+ if (cl->server->anoncred_s && !--_client_connected)
+ gnutls_anon_free_server_credentials(cl->server->anoncred_s);
+ _ecore_con_ssl_client_prepare_gnutls(cl);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static int
+_ecore_con_ssl_client_read_gnutls(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_recv(cl->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+static int
+_ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ int num;
+
+ num = gnutls_record_send(cl->session, buf, size);
+ if (num > 0)
+ return num;
+ if ((num == GNUTLS_E_AGAIN) ||
+ (num == GNUTLS_E_REHANDSHAKE) ||
+ (num == GNUTLS_E_INTERRUPTED))
+ return 0;
+ return -1;
+}
+
+#elif USE_OPENSSL
+
+/*
+ * OpenSSL
+ */
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_init_openssl(void)
+{
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_shutdown_openssl(void)
+{
+ // FIXME nothing to do ?
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static void
+_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr)
+{
+ svr->ssl = NULL;
+ svr->ssl_ctx = NULL;
+ svr->ssl_err = SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
+{
+ switch (svr->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2:
+ /* Unsafe version of SSL */
+ if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_SSL3:
+ if (!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_TLS:
+ if (!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+ if (!(svr->ssl = SSL_new(svr->ssl_ctx)))
+ {
+ SSL_CTX_free(svr->ssl_ctx);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ SSL_set_fd(svr->ssl, svr->fd);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_shutdown_openssl(Ecore_Con_Server *svr)
+{
+ if (svr->ssl)
+ {
+ if (!SSL_shutdown(svr->ssl))
+ SSL_shutdown(svr->ssl);
+ SSL_free(svr->ssl);
+ }
+ if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx);
+
+ _ecore_con_ssl_server_prepare_openssl(svr);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+/* Tries to connect an Ecore_Con_Server to an SSL host.
+ * Returns 1 on success, -1 on fatal errors and 0 if the caller
+ * should try again later.
+ */
+static Ecore_Con_State
+_ecore_con_ssl_server_try_openssl(Ecore_Con_Server *svr)
+{
+ int res, flag = 0;
+
+ if ((res = SSL_connect(svr->ssl)) == 1)
+ return ECORE_CON_CONNECTED;
+
+ svr->ssl_err = SSL_get_error(svr->ssl, res);
+
+ switch (svr->ssl_err)
+ {
+ case SSL_ERROR_NONE:
+ return ECORE_CON_CONNECTED;
+ case SSL_ERROR_WANT_READ:
+ flag = ECORE_FD_READ;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ flag = ECORE_FD_WRITE;
+ break;
+ default:
+ return ECORE_CON_DISCONNECTED;
+ }
+
+ if (svr->fd_handler && flag)
+ ecore_main_fd_handler_active_set(svr->fd_handler, flag);
+
+ return ECORE_CON_INPROGRESS;
+}
+
+static int
+_ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ int num;
+
+ num = SSL_read(svr->ssl, buf, size);
+ svr->ssl_err = SSL_get_error(svr->ssl, num);
+
+ if (svr->fd_handler)
+ {
+ if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (svr->ssl_err == SSL_ERROR_SYSCALL) ||
+ (svr->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+static int
+_ecore_con_ssl_server_write_openssl(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ int num;
+
+ num = SSL_write(svr->ssl, buf, size);
+ svr->ssl_err = SSL_get_error(svr->ssl, num);
+
+ if (svr->fd_handler)
+ {
+ if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
+ else if (svr->ssl && svr->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((svr->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (svr->ssl_err == SSL_ERROR_SYSCALL) ||
+ (svr->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+static void
+_ecore_con_ssl_client_prepare_openssl(Ecore_Con_Client *cl)
+{
+ cl->ssl = NULL;
+ cl->ssl_ctx = NULL;
+ cl->ssl_err = SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
+{
+ switch (cl->server->type & ECORE_CON_SSL)
+ {
+ case ECORE_CON_USE_SSL2:
+ /* Unsafe version of SSL */
+ if (!(cl->ssl_ctx = SSL_CTX_new(SSLv2_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_SSL3:
+ if (!(cl->ssl_ctx = SSL_CTX_new(SSLv3_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ case ECORE_CON_USE_TLS:
+ if (!(cl->ssl_ctx = SSL_CTX_new(TLSv1_client_method())))
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ break;
+ default:
+ return ECORE_CON_SSL_ERROR_NONE;
+ }
+ if (!(cl->ssl = SSL_new(cl->ssl_ctx)))
+ {
+ SSL_CTX_free(cl->ssl_ctx);
+ return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
+ }
+
+ SSL_set_fd(cl->ssl, cl->fd);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_shutdown_openssl(Ecore_Con_Client *cl)
+{
+ if (cl->ssl)
+ {
+ if (!SSL_shutdown(cl->ssl))
+ SSL_shutdown(cl->ssl);
+ SSL_free(cl->ssl);
+ }
+ if (cl->ssl_ctx) SSL_CTX_free(cl->ssl_ctx);
+
+ _ecore_con_ssl_client_prepare_openssl(cl);
+
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static int
+_ecore_con_ssl_client_read_openssl(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ int num;
+
+ num = SSL_read(cl->ssl, buf, size);
+ cl->ssl_err = SSL_get_error(cl->ssl, num);
+
+ if (cl->fd_handler)
+ {
+ if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
+ else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (cl->ssl_err == SSL_ERROR_SYSCALL) ||
+ (cl->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+static int
+_ecore_con_ssl_client_write_openssl(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ int num;
+
+ num = SSL_write(cl->ssl, buf, size);
+ cl->ssl_err = SSL_get_error(cl->ssl, num);
+
+ if (cl->fd_handler)
+ {
+ if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_READ)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
+ else if (cl->ssl && cl->ssl_err == SSL_ERROR_WANT_WRITE)
+ ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE);
+ }
+
+ if ((cl->ssl_err == SSL_ERROR_ZERO_RETURN) ||
+ (cl->ssl_err == SSL_ERROR_SYSCALL) ||
+ (cl->ssl_err == SSL_ERROR_SSL))
+ return -1;
+ if (num < 0)
+ return 0;
+ return num;
+}
+
+#else
+
+/*
+ * No Ssl
+ */
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_init_none(void)
+{
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_shutdown_none(void)
+{
+ return ECORE_CON_SSL_ERROR_NONE;
+}
+
+static void
+_ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr)
+{
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+/* Tries to connect an Ecore_Con_Server to an SSL host.
+ * Returns 1 on success, -1 on fatal errors and 0 if the caller
+ * should try again later.
+ */
+static Ecore_Con_State
+_ecore_con_ssl_server_try_none(Ecore_Con_Server *svr)
+{
+ return ECORE_CON_DISCONNECTED;
+}
+
+static int
+_ecore_con_ssl_server_read_none(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ return -1;
+}
+
+static int
+_ecore_con_ssl_server_write_none(Ecore_Con_Server *svr, unsigned char *buf, int size)
+{
+ return -1;
+}
+
+static void
+_ecore_con_ssl_client_prepare_none(Ecore_Con_Client *cl)
+{
+ return;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+static Ecore_Con_Ssl_Error
+_ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl)
+{
+ return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
+}
+
+static int
+_ecore_con_ssl_client_read_none(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ return -1;
+}
+
+static int
+_ecore_con_ssl_client_write_none(Ecore_Con_Client *cl, unsigned char *buf, int size)
+{
+ return -1;
+}
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * For info on how to use libcurl, see:
+ * http://curl.haxx.se/libcurl/c/libcurl-tutorial.html
+ */
+
+/*
+ * Brief usage:
+ * 1. Create an Ecore_Con_Url object
+ * 2. Register to receive the ECORE_CON_EVENT_URL_COMPLETE event
+ * (and optionally the ECORE_CON_EVENT_URL_DATA event to receive
+ * the response, e.g. for HTTP/FTP downloads)
+ * 3. Set the URL with ecore_con_url_url_set(...);
+ * 4. Perform the operation with ecore_con_url_send(...);
+ *
+ * Note that it is good to reuse Ecore_Con_Url objects wherever possible, but
+ * bear in mind that each one can only perform one operation at a time.
+ * You need to wait for the ECORE_CON_EVENT_URL_COMPLETE event before re-using
+ * or destroying the object.
+ *
+ * Example Usage 1 (HTTP GET):
+ * ecore_con_url_url_set(url_con, "http://www.google.com");
+ * ecore_con_url_send(url_con, NULL, 0, NULL);
+ *
+ * Example usage 2 (HTTP POST):
+ * ecore_con_url_url_set(url_con, "http://www.example.com/post_handler.cgi");
+ * ecore_con_url_send(url_con, data, data_length, "multipart/form-data");
+ *
+ * Example Usage 3 (FTP download):
+ * ecore_con_url_url_set(url_con, "ftp://ftp.example.com/pub/myfile");
+ * ecore_con_url_send(url_con, NULL, 0, NULL);
+ *
+ * Example Usage 4 (FTP upload as ftp://ftp.example.com/file):
+ * ecore_con_url_url_set(url_con, "ftp://ftp.example.com");
+ * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass", NULL);
+ *
+ * Example Usage 5 (FTP upload as ftp://ftp.example.com/dir/file):
+ * ecore_con_url_url_set(url_con, "ftp://ftp.example.com");
+ * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass","dir");
+ *
+ * FIXME: Support more CURL features: Authentication, Progress callbacks and more...
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Con.h"
+#include "ecore_con_private.h"
+
+/**
+ * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions
+ *
+ * Utility functions that set up, use and shut down the Ecore URL
+ * Connection library.
+ * FIXME: write detailed description
+ */
+
+int ECORE_CON_EVENT_URL_DATA = 0;
+int ECORE_CON_EVENT_URL_COMPLETE = 0;
+int ECORE_CON_EVENT_URL_PROGRESS = 0;
+
+#ifdef HAVE_CURL
+static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_con_url_perform(Ecore_Con_Url *url_con);
+static size_t _ecore_con_url_header_cb(void *ptr, size_t size, size_t nitems, void *stream);
+static size_t _ecore_con_url_data_cb(void *buffer, size_t size, size_t nitems, void *userp);
+static int _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
+static size_t _ecore_con_url_read_cb(void *ptr, size_t size, size_t nitems, void *stream);
+static void _ecore_con_event_url_free(void *data __UNUSED__, void *ev);
+static int _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match);
+static int _ecore_con_url_idler_handler(void *data __UNUSED__);
+
+static Ecore_Idler *_fd_idler_handler = NULL;
+static Eina_List *_url_con_list = NULL;
+static CURLM *curlm = NULL;
+static fd_set _current_fd_set;
+static int init_count = 0;
+static Ecore_Timer *_curl_timeout = NULL;
+
+typedef struct _Ecore_Con_Url_Event Ecore_Con_Url_Event;
+struct _Ecore_Con_Url_Event
+{
+ int type;
+ void *ev;
+};
+
+static int
+_url_complete_idler_cb(void *data)
+{
+ Ecore_Con_Url_Event *lev;
+
+ lev = data;
+ ecore_event_add(lev->type, lev->ev, _ecore_con_event_url_free, NULL);
+ free(lev);
+
+ return 0;
+}
+
+static void
+_url_complete_push_event(int type, void *ev)
+{
+ Ecore_Con_Url_Event *lev;
+
+ lev = malloc(sizeof(Ecore_Con_Url_Event));
+ lev->type = type;
+ lev->ev = ev;
+
+ ecore_idler_add(_url_complete_idler_cb, lev);
+}
+
+#endif
+
+/**
+ * Initialises the Ecore_Con_Url library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_init(void)
+{
+#ifdef HAVE_CURL
+ init_count++;
+
+ if (init_count > 1) return init_count;
+
+ if (!ECORE_CON_EVENT_URL_DATA)
+ {
+ ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
+ ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
+ ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
+ }
+
+ if (!curlm)
+ {
+ long ms;
+
+ FD_ZERO(&_current_fd_set);
+ if (curl_global_init(CURL_GLOBAL_NOTHING))
+ {
+ while (_url_con_list)
+ ecore_con_url_destroy(eina_list_data_get(_url_con_list));
+ return 0;
+ }
+
+ curlm = curl_multi_init();
+ if (!curlm)
+ {
+ while (_url_con_list)
+ ecore_con_url_destroy(eina_list_data_get(_url_con_list));
+
+ init_count--;
+ return 0;
+ }
+
+ curl_multi_timeout(curlm, &ms);
+ if (ms <= 0) ms = 1000;
+
+ _curl_timeout = ecore_timer_add((double) ms / 1000, _ecore_con_url_idler_handler, (void *) 0xACE);
+ ecore_timer_freeze(_curl_timeout);
+ }
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Shuts down the Ecore_Con_Url library.
+ * @return Number of calls that still uses Ecore_Con_Url
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_shutdown(void)
+{
+#ifdef HAVE_CURL
+ if (!init_count) return 0;
+
+ init_count--;
+
+ if (init_count != 0) return init_count;
+
+ if (_fd_idler_handler)
+ ecore_idler_del(_fd_idler_handler);
+ _fd_idler_handler = NULL;
+
+ if (_curl_timeout)
+ ecore_timer_del(_curl_timeout);
+ _curl_timeout = NULL;
+
+ while (_url_con_list)
+ ecore_con_url_destroy(eina_list_data_get(_url_con_list));
+
+ if (curlm)
+ {
+ curl_multi_cleanup(curlm);
+ curlm = NULL;
+ }
+
+ curl_global_cleanup();
+#endif
+ return 1;
+}
+
+/**
+ * Creates and initializes a new Ecore_Con_Url connection object.
+ *
+ * Creates and initializes a new Ecore_Con_Url connection object that can be
+ * uesd for sending requests.
+ *
+ * @param url URL that will receive requests. Can be changed using
+ * ecore_con_url_url_set.
+ *
+ * @return NULL on error, a new Ecore_Con_Url on success.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_custom_new()
+ * @see ecore_con_url_url_set()
+ */
+EAPI Ecore_Con_Url *
+ecore_con_url_new(const char *url)
+{
+#ifdef HAVE_CURL
+ Ecore_Con_Url *url_con;
+
+ if (!init_count) return NULL;
+
+ url_con = calloc(1, sizeof(Ecore_Con_Url));
+ if (!url_con) return NULL;
+
+ url_con->curl_easy = curl_easy_init();
+ if (!url_con->curl_easy)
+ {
+ free(url_con);
+ return NULL;
+ }
+
+ ECORE_MAGIC_SET(url_con, ECORE_MAGIC_CON_URL);
+
+ ecore_con_url_url_set(url_con, url);
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEFUNCTION,
+ _ecore_con_url_data_cb);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEDATA, url_con);
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION,
+ _ecore_con_url_progress_cb);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSDATA, url_con);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_FALSE);
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_HEADERFUNCTION, _ecore_con_url_header_cb);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_HEADERDATA, url_con);
+
+ /*
+ * FIXME: Check that these timeouts are sensible defaults
+ * FIXME: Provide a means to change these timeouts
+ */
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_CONNECTTIMEOUT, 30);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEOUT, 300);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_FOLLOWLOCATION, 1);
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate");
+
+ url_con->fd = -1;
+ url_con->write_fd = -1;
+ url_con->additional_headers = NULL;
+ url_con->response_headers = NULL;
+
+ return url_con;
+#else
+ return NULL;
+ url = NULL;
+#endif
+}
+
+/**
+ * Creates a custom connection object.
+ *
+ * Creates and initializes a new Ecore_Con_Url for a custom request (e.g. HEAD,
+ * SUBSCRIBE and other obscure HTTP requests). This object should be used like
+ * one created with ecore_con_url_new().
+ *
+ * @param url URL that will receive requests
+ * @param custom_request Custom request (e.g. GET, POST, HEAD, PUT, etc)
+ *
+ * @return NULL on error, a new Ecore_Con_Url on success.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_new()
+ * @see ecore_con_url_url_set()
+ */
+EAPI Ecore_Con_Url *
+ecore_con_url_custom_new(const char *url, const char *custom_request)
+{
+#ifdef HAVE_CURL
+ Ecore_Con_Url *url_con;
+
+ if (!url) return NULL;
+ if (!custom_request) return NULL;
+
+ url_con = ecore_con_url_new(url);
+
+ if (!url_con) return NULL;
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_CUSTOMREQUEST, custom_request);
+
+ return url_con;
+#else
+ return NULL;
+ url = NULL;
+ custom_request = NULL;
+#endif
+}
+
+/**
+ * Destroys a Ecore_Con_Url connection object.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_new()
+ */
+EAPI void
+ecore_con_url_destroy(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+ char *s;
+
+ if (!url_con) return;
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_destroy");
+ return;
+ }
+
+ ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
+ if(url_con->fd != -1)
+ {
+ FD_CLR(url_con->fd, &_current_fd_set);
+ if (url_con->fd_handler)
+ ecore_main_fd_handler_del(url_con->fd_handler);
+ url_con->fd = -1;
+ url_con->fd_handler = NULL;
+ }
+
+ if (url_con->post)
+ curl_formfree(url_con->post);
+ url_con->post = NULL;
+
+ if (url_con->curl_easy)
+ {
+ // FIXME: For an unknown reason, progress continue to arrive after destruction
+ // this prevent any further call to the callback.
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL);
+
+ if (url_con->active)
+ {
+ url_con->active = 0;
+
+ curl_multi_remove_handle(curlm, url_con->curl_easy);
+ }
+ curl_easy_cleanup(url_con->curl_easy);
+ }
+ _url_con_list = eina_list_remove(_url_con_list, url_con);
+ curl_slist_free_all(url_con->headers);
+ EINA_LIST_FREE(url_con->additional_headers, s)
+ free(s);
+ EINA_LIST_FREE(url_con->response_headers, s)
+ free(s);
+ free(url_con->url);
+ free(url_con);
+#else
+ return;
+ url_con = NULL;
+#endif
+}
+
+/**
+ * Sets the URL to send the request to.
+ *
+ * @param url_con Connection object through which the request will be sent.
+ * @param url URL that will receive the request
+ *
+ * @return 1 on success, 0 on error.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_url_set");
+ return 0;
+ }
+
+ if (url_con->active) return 0;
+
+ if (url_con->url) free(url_con->url);
+ url_con->url = NULL;
+ if (url) url_con->url = strdup(url);
+ if (url_con->url)
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_URL, url_con->url);
+ else
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_URL, "");
+ return 1;
+#else
+ return 0;
+ url_con = NULL;
+ url = NULL;
+#endif
+}
+
+/**
+ * Associates data with a connection object.
+ *
+ * Associates data with a connection object, which can be retrieved later with
+ * ecore_con_url_data_get()).
+ *
+ * @param url_con Connection object to associate data.
+ * @param data Data to be set.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_data_get()
+ */
+EAPI void
+ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_set");
+ return;
+ }
+
+ url_con->data = data;
+#else
+ return;
+ url_con = NULL;
+ data = NULL;
+#endif
+}
+
+/**
+ * Adds an additional header to the request connection object.
+ *
+ * Adds an additional header to the request connection object. This addition
+ * will be valid for only one ecore_con_url_send() call.
+ *
+ * @param url_con Connection object
+ * @param key Header key
+ * @param value Header value
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_send()
+ * @see ecore_con_url_additional_headers_clear()
+ */
+EAPI void
+ecore_con_url_additional_header_add(Ecore_Con_Url *url_con, const char *key, const char *value)
+{
+#ifdef HAVE_CURL
+ char *tmp;
+
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_additional_header_add");
+ return;
+ }
+
+ tmp = malloc(strlen(key) + strlen(value) + 3);
+ if (!tmp) return ;
+ sprintf(tmp, "%s: %s", key, value);
+ url_con->additional_headers = eina_list_append(url_con->additional_headers, tmp);
+#else
+ return;
+ url_con = NULL;
+ key = NULL;
+ value = NULL;
+#endif
+}
+
+/*
+ * Cleans additional headers.
+ *
+ * Cleans additional headers associated with a connection object (previously
+ * added with ecore_con_url_additional_header_add()).
+ *
+ * @param url_con Connection object to clean additional headers.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_additional_header_add()
+ * @see ecore_con_url_send()
+ */
+EAPI void
+ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+ char *s;
+
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_additional_headers_clear");
+ return;
+ }
+
+ EINA_LIST_FREE(url_con->additional_headers, s)
+ free(s);
+#else
+ return;
+ url_con = NULL;
+#endif
+}
+
+/**
+ * Retrieves data associated with a Ecore_Con_Url connection object.
+ *
+ * Retrieves data associated with a Ecore_Con_Url connection object (previously
+ * set with ecore_con_url_data_set()).
+ *
+ * @param Connection object to retrieve data from.
+ *
+ * @return Data associated with the given object.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_data_set()
+ */
+EAPI void *
+ecore_con_url_data_get(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_get");
+ return NULL;
+ }
+
+ return url_con->data;
+#else
+ return NULL;
+ url_con = NULL;
+#endif
+}
+
+/**
+ * FIXME: To be documented.
+ * @return FIXME: To be documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI void
+ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t tm)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_time");
+ return;
+ }
+
+ url_con->condition = condition;
+ url_con->time = tm;
+#else
+ return;
+ url_con = NULL;
+ condition = 0;
+ tm = 0;
+#endif
+}
+
+/**
+ * Setup a file for receiving request data.
+ *
+ * Setups a file to have response data written into. Note that
+ * ECORE_CON_EVENT_URL_DATA events will not be emitted if a file has been set to
+ * receive the response data.
+ *
+ * @param url_con Connection object to set file
+ * @param fd File descriptor associated with the file
+ *
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI void
+ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_set");
+ return ;
+ }
+ url_con->write_fd = fd;
+#endif
+}
+
+/**
+ * Retrieves the number of bytes received.
+ *
+ * Retrieves the number of bytes received on the last request of the given
+ * connection object.
+ *
+ * @param url_con Connection object which the request was sent on.
+ *
+ * @return Number of bytes received on request.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_send()
+ */
+EAPI int
+ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_received_bytes_get");
+ return -1;
+ }
+
+ return url_con->received;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Retrieves headers from last request sent.
+ *
+ * Retrieves a list containing the response headers. This function should be
+ * used after an ECORE_CON_EVENT_URL_COMPLETE event (headers should normally be
+ * ready at that time).
+ *
+ * @param url_con Connection object to retrieve response headers from.
+ *
+ * @return List of response headers. This list must not be modified by the user.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI const Eina_List *
+ecore_con_url_response_headers_get(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+ return url_con->response_headers;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * Sets url_con to use http auth, with given username and password, "safely" or not.
+ *
+ * @param url_con Connection object to perform a request on, previously created
+ * with ecore_con_url_new() or ecore_con_url_custom_new().
+ * @param username Username to use in authentication
+ * @param password Password to use in authentication
+ * @param safe Whether to use "safer" methods (eg, NOT http basic auth)
+ *
+ * @return 1 on success, 0 on error.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, const char *username, const char *password, Eina_Bool safe)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_httpauth_set");
+ return 0;
+ }
+# ifdef CURLOPT_USERNAME
+# ifdef CURLOPT_PASSWORD
+ if ((username != NULL) && (password != NULL))
+ {
+ if (safe)
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+ else
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password);
+ return 1;
+ }
+# endif
+# endif
+#endif
+ return 0;
+}
+
+/**
+ * Sends a request.
+ *
+ * @param url_con Connection object to perform a request on, previously created
+ * with ecore_con_url_new() or ecore_con_url_custom_new().
+ * @param data Payload (data sent on the request)
+ * @param length Payload length
+ * @param content_type Content type of the payload (e.g. text/xml)
+ *
+ * @return 1 on success, 0 on error.
+ *
+ * @ingroup Ecore_Con_Url_Group
+ *
+ * @see ecore_con_url_custom_new()
+ * @see ecore_con_url_additional_headers_clear()
+ * @see ecore_con_url_additional_header_add()
+ * @see ecore_con_url_data_set()
+ * @see ecore_con_url_data_get()
+ * @see ecore_con_url_response_headers_get()
+ */
+EAPI int
+ecore_con_url_send(Ecore_Con_Url *url_con, const void *data, size_t length, const char *content_type)
+{
+#ifdef HAVE_CURL
+ Eina_List *l;
+ const char *s;
+ char tmp[256];
+
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_send");
+ return 0;
+ }
+
+ if (url_con->active) return 0;
+ if (!url_con->url) return 0;
+
+ /* Free response headers from previous send() calls */
+ EINA_LIST_FREE(url_con->response_headers, s) free((char *)s);
+ url_con->response_headers = NULL;
+
+ curl_slist_free_all(url_con->headers);
+ url_con->headers = NULL;
+
+ if (data)
+ {
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, data);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length);
+
+ if (content_type && (strlen(content_type) < 200))
+ {
+ sprintf(tmp, "Content-type: %s", content_type);
+ url_con->headers = curl_slist_append(url_con->headers, tmp);
+ }
+ sprintf(tmp, "Content-length: %zu", length);
+ url_con->headers = curl_slist_append(url_con->headers, tmp);
+ }
+
+ switch (url_con->condition)
+ {
+ case ECORE_CON_URL_TIME_NONE:
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION,
+ CURL_TIMECOND_NONE);
+ break;
+ case ECORE_CON_URL_TIME_IFMODSINCE:
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION,
+ CURL_TIMECOND_IFMODSINCE);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, url_con->time);
+ break;
+ case ECORE_CON_URL_TIME_IFUNMODSINCE:
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION,
+ CURL_TIMECOND_IFUNMODSINCE);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, url_con->time);
+ break;
+ case ECORE_CON_URL_TIME_LASTMOD:
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMECONDITION,
+ CURL_TIMECOND_LASTMOD);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEVALUE, url_con->time);
+ break;
+ }
+
+ /* Additional headers */
+ EINA_LIST_FOREACH(url_con->additional_headers, l, s)
+ url_con->headers = curl_slist_append(url_con->headers, s);
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPHEADER, url_con->headers);
+
+ url_con->received = 0;
+
+ int res = _ecore_con_url_perform(url_con);
+
+ return res;
+#else
+ return 0;
+ url_con = NULL;
+ data = NULL;
+ length = 0;
+ content_type = NULL;
+#endif
+}
+
+/**
+ * Makes a FTP upload
+ * @return FIXME: To be more documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, const char *filename, const char *user, const char *pass, const char *upload_dir)
+{
+#ifdef HAVE_CURL
+ char url[4096];
+ char userpwd[4096];
+ FILE *fd;
+ struct stat file_info;
+
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_ftp_upload");
+ return 0;
+ }
+
+ if (url_con->active) return 0;
+ if (!url_con->url) return 0;
+ if (filename)
+ {
+ char tmp[PATH_MAX];
+
+ snprintf(tmp, PATH_MAX, "%s", filename);
+
+ if (stat(filename, &file_info)) return 0;
+ fd = fopen(filename, "rb");
+ if (upload_dir)
+ snprintf(url, sizeof(url), "ftp://%s/%s/%s", url_con->url,
+ upload_dir, basename(tmp));
+ else
+ snprintf(url, sizeof(url), "ftp://%s/%s", url_con->url,
+ basename(tmp));
+ snprintf(userpwd, sizeof(userpwd), "%s:%s", user, pass);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t)file_info.st_size);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_USERPWD, userpwd);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_UPLOAD, 1);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_READFUNCTION,
+ _ecore_con_url_read_cb);
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_READDATA, fd);
+ ecore_con_url_url_set(url_con, url);
+
+ return _ecore_con_url_perform(url_con);
+ }
+ else
+ return 0;
+#else
+ return 0;
+ url_con = NULL;
+ filename = NULL;
+ user = NULL;
+ pass = NULL;
+ upload_dir = NULL;
+#endif
+}
+
+/**
+ * Send a Curl httppost
+ * @return 1 on success, 0 on error.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_http_post_send(Ecore_Con_Url *url_con, void *httppost)
+{
+#ifdef HAVE_CURL
+ if (url_con->post)
+ curl_formfree(url_con->post);
+ url_con->post = NULL;
+
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_http_post_send");
+ return 0;
+ }
+
+ url_con->post = httppost;
+
+ if (url_con->active) return 0;
+ if (!url_con->url) return 0;
+
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPPOST, httppost);
+
+ return ecore_con_url_send(url_con, NULL, 0, NULL);
+#else
+ return 0;
+ url_con = NULL;
+#endif
+}
+
+/**
+ * Enable or disable libcurl verbose output, useful for debug
+ * @return FIXME: To be more documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI void
+ecore_con_url_verbose_set(Ecore_Con_Url *url_con, int verbose)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_verbose_set");
+ return;
+ }
+
+ if (url_con->active) return;
+ if (!url_con->url) return;
+ if (verbose == EINA_TRUE)
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, 1);
+ else
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, 0);
+#endif
+}
+
+/**
+ * Enable or disable EPSV extension
+ * @return FIXME: To be more documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI void
+ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, int use_epsv)
+{
+#ifdef HAVE_CURL
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_ftp_use_epsv_set");
+ return;
+ }
+
+ if (url_con->active) return;
+ if (!url_con->url) return;
+ if (use_epsv == EINA_TRUE)
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, 1);
+ else
+ curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, 0);
+#endif
+}
+
+#ifdef HAVE_CURL
+static int
+_ecore_con_url_suspend_fd_handler(void)
+{
+ Eina_List *l;
+ Ecore_Con_Url *url_con;
+ int deleted = 0;
+
+ if (!_url_con_list) return 0;
+
+ EINA_LIST_FOREACH(_url_con_list, l, url_con)
+ {
+ if (url_con->active && url_con->fd_handler)
+ {
+ ecore_main_fd_handler_del(url_con->fd_handler);
+ url_con->fd_handler = NULL;
+ deleted++;
+ }
+ }
+
+ return deleted;
+}
+
+static int
+_ecore_con_url_restart_fd_handler(void)
+{
+ Eina_List *l;
+ Ecore_Con_Url *url_con;
+ int activated = 0;
+
+ if (!_url_con_list) return 0;
+
+ EINA_LIST_FOREACH(_url_con_list, l, url_con)
+ {
+ if (url_con->fd_handler == NULL && url_con->fd != -1)
+ {
+ url_con->fd_handler =
+ ecore_main_fd_handler_add(url_con->fd, url_con->flags,
+ _ecore_con_url_fd_handler,
+ NULL, NULL, NULL);
+ activated++;
+ }
+ }
+
+ return activated;
+}
+
+static size_t
+_ecore_con_url_data_cb(void *buffer, size_t size, size_t nitems, void *userp)
+{
+ Ecore_Con_Url *url_con;
+ Ecore_Con_Event_Url_Data *e;
+ size_t real_size = size * nitems;
+
+ url_con = (Ecore_Con_Url *)userp;
+
+ if (!url_con) return -1;
+ if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+ {
+ ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_cb");
+ return -1;
+ }
+
+ url_con->received += real_size;
+
+ if (url_con->write_fd < 0)
+ {
+ e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * (real_size - 1));
+ if (e)
+ {
+ e->url_con = url_con;
+ e->size = real_size;
+ memcpy(e->data, buffer, real_size);
+ ecore_event_add(ECORE_CON_EVENT_URL_DATA, e,
+ _ecore_con_event_url_free, NULL);
+ }
+ }
+ else
+ {
+ ssize_t count = 0;
+ size_t total_size = real_size;
+ size_t offset = 0;
+
+ while (total_size > 0)
+ {
+ count = write(url_con->write_fd, (char*) buffer + offset, total_size);
+ if (count < 0)
+ {
+ if (errno != EAGAIN && errno != EINTR) return -1;
+ }
+ else
+ {
+ total_size -= count;
+ offset += count;
+ }
+ }
+ }
+
+ return real_size;
+}
+
+#define ECORE_CON_URL_TRANSMISSION(Transmit, Event, Url_con, Total, Now) \
+{ \
+ Ecore_Con_Event_Url_Progress *e; \
+ if ((Total != 0) || (Now != 0)) \
+ { \
+ e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress)); \
+ if (e) \
+ { \
+ e->url_con = url_con; \
+ e->total = Total; \
+ e->now = Now; \
+ ecore_event_add(Event, e, _ecore_con_event_url_free, NULL); \
+ } \
+ } \
+}
+
+static size_t
+_ecore_con_url_header_cb(void *ptr, size_t size, size_t nitems, void *stream)
+{
+ size_t real_size = size * nitems;
+ Ecore_Con_Url *url_con = stream;
+
+ char *header = malloc(sizeof(char)*(real_size + 1));
+ if (!header) return real_size;
+ memcpy(header, ptr, real_size);
+ header[real_size] = '\0';
+
+ url_con->response_headers = eina_list_append(url_con->response_headers,
+ header);
+
+ return real_size;
+}
+
+static int
+_ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
+{
+ Ecore_Con_Event_Url_Progress *e;
+ Ecore_Con_Url *url_con;
+
+ url_con = clientp;
+
+ e = malloc(sizeof(Ecore_Con_Event_Url_Progress));
+ if (e)
+ {
+ e->url_con = url_con;
+ e->down.total = dltotal;
+ e->down.now = dlnow;
+ e->up.total = ultotal;
+ e->up.now = ulnow;
+ ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e,
+ _ecore_con_event_url_free, NULL);
+ }
+
+ return 0;
+}
+
+static size_t
+_ecore_con_url_read_cb(void *ptr, size_t size, size_t nitems, void *stream)
+{
+ size_t retcode = fread(ptr, size, nitems, stream);
+
+ if (ferror((FILE*)stream))
+ {
+ fclose(stream);
+ return CURL_READFUNC_ABORT;
+ }
+ else if ((retcode == 0) || (retcode < nitems))
+ {
+ fclose((FILE*)stream);
+ return 0;
+ }
+ INF("*** We read %zu bytes from file", retcode);
+ return retcode;
+}
+
+static int
+_ecore_con_url_perform(Ecore_Con_Url *url_con)
+{
+ fd_set read_set, write_set, exc_set;
+ int fd_max, fd;
+ int flags, still_running;
+ int completed_immediately = 0;
+
+ _url_con_list = eina_list_append(_url_con_list, url_con);
+
+ url_con->active = 1;
+ curl_multi_add_handle(curlm, url_con->curl_easy);
+ /* This one can't be stopped, or the download never start. */
+ while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
+
+ completed_immediately = _ecore_con_url_process_completed_jobs(url_con);
+
+ if (!completed_immediately)
+ {
+ if (url_con->fd_handler)
+ ecore_main_fd_handler_del(url_con->fd_handler);
+ url_con->fd_handler = NULL;
+
+ /* url_con still active -- set up an fd_handler */
+ FD_ZERO(&read_set);
+ FD_ZERO(&write_set);
+ FD_ZERO(&exc_set);
+
+ /* Stupid curl, why can't I get the fd to the current added job? */
+ curl_multi_fdset(curlm, &read_set, &write_set, &exc_set, &fd_max);
+ for (fd = 0; fd <= fd_max; fd++)
+ {
+ if (!FD_ISSET(fd, &_current_fd_set))
+ {
+ flags = 0;
+ if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ;
+ if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE;
+ if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR;
+ if (flags)
+ {
+ long ms = 0;
+
+ curl_multi_timeout(curlm, &ms);
+ if (ms == 0) ms = 1000;
+
+ FD_SET(fd, &_current_fd_set);
+ url_con->fd = fd;
+ url_con->flags = flags;
+ url_con->fd_handler =
+ ecore_main_fd_handler_add(fd, flags,
+ _ecore_con_url_fd_handler,
+ NULL, NULL, NULL);
+ break;
+ }
+ }
+ }
+ if (!url_con->fd_handler)
+ {
+ /* Failed to set up an fd_handler */
+ ecore_timer_freeze(_curl_timeout);
+ curl_multi_remove_handle(curlm, url_con->curl_easy);
+ url_con->active = 0;
+ url_con->fd = -1;
+ return 0;
+ }
+ ecore_timer_thaw(_curl_timeout);
+ }
+
+ return 1;
+}
+
+static int
+_ecore_con_url_idler_handler(void *data)
+{
+ double start;
+ int done = 1, still_running;
+
+ start = ecore_time_get();
+ while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM)
+ /* make this not more than a frametime to keep interactivity high */
+ if ((ecore_time_get() - start) > ecore_animator_frametime_get())
+ {
+ done = 0;
+ break;
+ }
+
+ _ecore_con_url_process_completed_jobs(NULL);
+
+ if (done)
+ {
+ _ecore_con_url_restart_fd_handler();
+ _fd_idler_handler = NULL;
+
+ if (!_url_con_list)
+ ecore_timer_freeze(_curl_timeout);
+ return data == (void*) 0xACE ? 1 : 0;
+ }
+
+ return 1;
+}
+
+static int
+_ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ _ecore_con_url_suspend_fd_handler();
+
+ if (_fd_idler_handler == NULL)
+ _fd_idler_handler = ecore_idler_add(_ecore_con_url_idler_handler, NULL);
+
+ return 1;
+}
+
+static int
+_ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
+{
+ Eina_List *l;
+ Ecore_Con_Url *url_con;
+ Ecore_Con_Event_Url_Complete *e;
+ CURLMsg *curlmsg;
+ int n_remaining;
+ int job_matched = 0;
+
+ /* Loop jobs and check if any are done */
+ while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
+ {
+ if (curlmsg->msg != CURLMSG_DONE) continue;
+
+ /* find the job which is done */
+ EINA_LIST_FOREACH(_url_con_list, l, url_con)
+ {
+ if (curlmsg->easy_handle == url_con->curl_easy)
+ {
+ if (url_con_to_match && (url_con == url_con_to_match))
+ job_matched = 1;
+ if(url_con->fd != -1)
+ {
+ FD_CLR(url_con->fd, &_current_fd_set);
+ if (url_con->fd_handler)
+ ecore_main_fd_handler_del(url_con->fd_handler);
+ url_con->fd = -1;
+ url_con->fd_handler = NULL;
+ }
+ _url_con_list = eina_list_remove(_url_con_list, url_con);
+ url_con->active = 0;
+ e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
+ if (e)
+ {
+ e->url_con = url_con;
+ e->status = 0;
+ if (curlmsg->data.result == CURLE_OK)
+ {
+ long status; /* curl API uses long, not int */
+
+ status = 0;
+ curl_easy_getinfo(curlmsg->easy_handle, CURLINFO_RESPONSE_CODE, &status);
+ e->status = status;
+ }
+
+ _url_complete_push_event(ECORE_CON_EVENT_URL_COMPLETE, e);
+ }
+ curl_multi_remove_handle(curlm, url_con->curl_easy);
+ break;
+ }
+ }
+ }
+
+ return job_matched;
+}
+
+static void
+_ecore_con_event_url_free(void *data __UNUSED__, void *ev)
+{
+ free(ev);
+}
+
+#endif
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_config.la
+ecore_config_ipc_ecore.la
+system.db
--- /dev/null
+#ifndef _ECORE_CONFIG_H
+# define _ECORE_CONFIG_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file
+ * @brief Provides the Enlightened Property Library.
+ *
+ * This file provies all headers and structs for use with Ecore_Config.
+ * Using individual header files should not be necessary.
+ */
+
+# define DIR_DELIMITER '/'
+# define ECORE_CONFIG_FLOAT_PRECISION 1000
+
+/* FIXME: this should only be included if evas is present */
+# include <Evas.h>
+
+# define ECORE_CONFIG_GLOBAL_ID "_system"
+
+/* structures */
+
+/**
+ * Valid configuration property types.
+ */
+typedef enum Ecore_Config_Type
+{
+ ECORE_CONFIG_NIL = 0, /**< Property with no value. */
+ ECORE_CONFIG_INT = 1, /**< Integer property type. */
+ ECORE_CONFIG_FLT = 2, /**< Float property type. */
+ ECORE_CONFIG_STR = 3, /**< String property type. */
+ ECORE_CONFIG_RGB = 4, /**< Colour property type. */
+ ECORE_CONFIG_THM = 5, /**< Theme property type. */
+ ECORE_CONFIG_BLN = 6, /**< Boolean property type. */
+ ECORE_CONFIG_SCT = 7, /**< Structure property type */
+} Ecore_Config_Type;
+
+typedef enum Ecore_Config_Flag
+{
+ ECORE_CONFIG_FLAG_NONE = 0,
+ ECORE_CONFIG_FLAG_BOUNDS = 1,
+ ECORE_CONFIG_FLAG_MODIFIED = 2,
+ ECORE_CONFIG_FLAG_SYSTEM = 4,
+ ECORE_CONFIG_FLAG_CMDLN = 8
+} Ecore_Config_Flag;
+
+/**
+ * Property change callback function prototype.
+ */
+typedef int (*Ecore_Config_Listener) (const char *key,
+ const Ecore_Config_Type type,
+ const int tag, void *data);
+
+typedef struct Ecore_Config_Listener_List
+{
+ Ecore_Config_Listener listener;
+ const char *name;
+ void *data;
+ int tag;
+ struct Ecore_Config_Listener_List *next;
+} Ecore_Config_Listener_List;
+
+/**
+ * The actual property for storing a key-value pair.
+ */
+typedef struct Ecore_Config_Prop
+{
+ char *key; /* Property key. */
+ char *description; /* Description set by ecore_config_descibe. */
+ char short_opt; /* short identifier on command line (-f) */
+ char *long_opt; /* long identifier on command line (--foo) */
+ char *ptr; /* Used as the value when the property is a string or theme. */
+ Ecore_Config_Type type; /* Property type. */
+ long val; /* Used as the value when the property is an integer, float or colour. */
+ long lo; /* Lower bound for the value when the property is an integer or float. */
+ long hi; /* Higher bound for the value when the property is an integer or float. */
+ long step; /* Increment for the value when the property is an integer or float. */
+ Ecore_Config_Flag flags; /// < Configuration flags.
+ Ecore_Config_Listener_List *listeners; /* List of change listeners. */
+ void *data; /// < Stores extra data for the property.
+ struct Ecore_Config_Prop *parent; /* if we are in a struct we have a parent to notify of changes etc */
+ struct Ecore_Config_Prop *next; /* Pointer to the next property in the list. */
+} Ecore_Config_Prop;
+
+/*
+ * A container for a list of properties. Provided so that an
+ * application can use different set of properties at any time. This
+ * is useful for multiple window support.
+ */
+typedef struct Ecore_Config_Bundle
+{
+ char *identifier; /* Identifier for this set of properties (window ID for example) */
+ char *owner; /* This is used to store the application name related to the bundle */
+ long serial; /* Unique identifier to identify bundle */
+ Ecore_Config_Prop *data; /* Pointer to root of property list */
+ void *user_data; /* App specific pointer to "other data" */
+ struct Ecore_Config_Bundle *next; /* Pointer to next bundle in this application */
+} Ecore_Config_Bundle;
+
+typedef struct Ecore_Config_Server
+{
+ void *server;
+ char *name;
+ Ecore_Config_Bundle *bundles; /* data anchor */
+ struct Ecore_Config_Server *next;
+} Ecore_Config_Server;
+
+# ifdef __cplusplus
+extern "C"
+{
+# endif
+
+/* global ptrs to save passing them through the API */
+ EAPI extern Ecore_Config_Server *__ecore_config_server_global;
+ EAPI extern Ecore_Config_Server *__ecore_config_server_local;
+ EAPI extern Ecore_Config_Bundle *__ecore_config_bundle_local;
+ EAPI extern char *__ecore_config_app_name;
+
+ EAPI Ecore_Config_Prop *ecore_config_get(const char *key);
+ EAPI const char *ecore_config_type_get(const Ecore_Config_Prop *e);
+ EAPI int ecore_config_boolean_get(const char *key);
+ EAPI char *ecore_config_string_get(const char *key);
+ EAPI long ecore_config_int_get(const char *key);
+ EAPI int ecore_config_argb_get(const char *key, int *a, int *r,
+ int *g, int *b);
+ EAPI long ecore_config_argbint_get(const char *key);
+ EAPI char *ecore_config_argbstr_get(const char *key);
+ EAPI float ecore_config_float_get(const char *key);
+ EAPI char *ecore_config_theme_get(const char *key);
+ EAPI char *ecore_config_as_string_get(const char *key);
+ EAPI int ecore_config_bound(Ecore_Config_Prop *e);
+ EAPI int ecore_config_describe(const char *key, const char *desc);
+ EAPI int ecore_config_short_opt_set(const char *key,
+ char short_opt);
+ EAPI int ecore_config_long_opt_set(const char *key,
+ const char *long_opt);
+ EAPI int ecore_config_set(const char *key, const char *val);
+ EAPI int ecore_config_typed_set(const char *key, const void *val,
+ int type);
+ EAPI int ecore_config_boolean_set(const char *key, int val);
+ EAPI int ecore_config_string_set(const char *key, const char *val);
+ EAPI int ecore_config_int_set(const char *key, int val);
+ EAPI int ecore_config_argb_set(const char *key, int a, int r, int g, int b);
+ EAPI int ecore_config_argbint_set(const char *key, long argb);
+ EAPI int ecore_config_argbstr_set(const char *key, const char *val);
+ EAPI int ecore_config_float_set(const char *key, float val);
+ EAPI int ecore_config_theme_set(const char *key, const char *val);
+ EAPI int ecore_config_theme_preview_group_set(const char *key,
+ const char *group);
+ EAPI int ecore_config_as_string_set(const char *key, const char *val);
+
+ EAPI int ecore_config_default(const char *key, const char *val,
+ float lo, float hi, float step);
+ EAPI int ecore_config_typed_default(const char *key, const void *val,
+ int type);
+ EAPI int ecore_config_boolean_default(const char *key, int val);
+ EAPI int ecore_config_int_default(const char *key, int val);
+ EAPI int ecore_config_int_default_bound(const char *key, int val,
+ int lo, int hi, int step);
+ EAPI int ecore_config_string_default(const char *key, const char *val);
+ EAPI int ecore_config_float_default(const char *key, float val);
+ EAPI int ecore_config_float_default_bound(const char *key,
+ float val, float lo,
+ float hi, float step);
+ EAPI int ecore_config_argb_default(const char *key, int a, int r, int g, int b);
+ EAPI int ecore_config_argbint_default(const char *key, long argb);
+ EAPI int ecore_config_argbstr_default(const char *key, const char *val);
+ EAPI int ecore_config_theme_default(const char *key, const char *val);
+ EAPI int ecore_config_struct_default(const char *key);
+ EAPI int ecore_config_struct_int_add(const char *key, const char *name, int val);
+ EAPI int ecore_config_struct_float_add(const char *key, const char *name, float val);
+ EAPI int ecore_config_struct_create(const char *key);
+ EAPI int ecore_config_struct_string_add(const char *key, const char *name, const char* val);
+ EAPI int ecore_config_struct_theme_add(const char *key, const char *name, const char* val);
+ EAPI int ecore_config_struct_argb_add(const char *key, const char *name, int a, int r, int g, int b);
+ EAPI int ecore_config_struct_boolean_add(const char *key, const char *name, int val);
+ EAPI int ecore_config_struct_get(const char *key, void *data);
+
+ EAPI int ecore_config_listen(const char *name, const char *key,
+ Ecore_Config_Listener listener,
+ int tag, void *data);
+ EAPI int ecore_config_deaf(const char *name, const char *key,
+ Ecore_Config_Listener listener);
+ EAPI Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Prop *e);
+ EAPI int ecore_config_type_guess(const char *key, const char *val);
+
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_new(Ecore_Config_Server *srv,
+ const char *id);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_1st_get(Ecore_Config_Server *srv);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_next_get(Ecore_Config_Bundle *ns);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_by_serial_get(Ecore_Config_Server *srv,
+ long serial);
+ EAPI Ecore_Config_Bundle *ecore_config_bundle_by_label_get(Ecore_Config_Server *srv,
+ const char *label);
+ EAPI long ecore_config_bundle_serial_get(Ecore_Config_Bundle *ns);
+ EAPI char *ecore_config_bundle_label_get(Ecore_Config_Bundle *ns);
+
+ EAPI int ecore_config_init(const char *name);
+ EAPI int ecore_config_shutdown(void);
+
+ EAPI int ecore_config_system_init(void);
+ EAPI int ecore_config_system_shutdown(void);
+
+ EAPI int ecore_config_load(void);
+ EAPI int ecore_config_file_load(const char *file);
+ EAPI int ecore_config_save(void);
+ EAPI int ecore_config_file_save(const char *file);
+
+/* error codes */
+# define ECORE_CONFIG_ERR_NOTSUPP (-16)
+# define ECORE_CONFIG_ERR_NOFILE (-15)
+# define ECORE_CONFIG_ERR_META_DLFAIL (-14)
+# define ECORE_CONFIG_ERR_META_FILE (-13)
+# define ECORE_CONFIG_ERR_META_FORMAT (-12)
+# define ECORE_CONFIG_ERR_MONMIS (-11)
+# define ECORE_CONFIG_ERR_NOEXEC (-10)
+# define ECORE_CONFIG_ERR_PARTIAL (-9)
+# define ECORE_CONFIG_ERR_PATHEX (-8)
+# define ECORE_CONFIG_ERR_TYPEMISMATCH (-7)
+# define ECORE_CONFIG_ERR_MUTEX (-6)
+# define ECORE_CONFIG_ERR_NOTFOUND (-5) /* Error indicating that the item searched for could not be found. */
+# define ECORE_CONFIG_ERR_OOM (-4) /* Error given when the program runs out of memory. */
+# define ECORE_CONFIG_ERR_IGNORED (-3) /* Error occurred, but was ignored. */
+# define ECORE_CONFIG_ERR_NODATA (-2) /* Error given when necessary data is not provided. */
+# define ECORE_CONFIG_ERR_FAIL (-1) /* Failure result. */
+# define ECORE_CONFIG_ERR_SUCC (0) /* Success result. */
+
+# define ECORE_CONFIG_PARSE_HELP (-2) /* Help was displayed */
+# define ECORE_CONFIG_PARSE_EXIT (-1) /* An error occurred */
+# define ECORE_CONFIG_PARSE_CONTINUE (0) /* Arguments parsed successfully */
+
+/* convenience mathods in convenience.c */
+ /* FIXME: this should only be included if evas is present */
+ EAPI int ecore_config_evas_font_path_apply(Evas *evas);
+ EAPI char *ecore_config_theme_search_path_get(void);
+ EAPI int ecore_config_theme_search_path_append(const char *append);
+
+ EAPI char *ecore_config_theme_default_path_get(void);
+ EAPI char *ecore_config_theme_with_path_from_name_get(char *name);
+ EAPI char *ecore_config_theme_with_path_get(const char *key);
+ EAPI void ecore_config_args_display(void);
+ EAPI int ecore_config_args_parse(void);
+ EAPI void ecore_config_args_callback_str_add(char short_opt,
+ char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data);
+ EAPI void ecore_config_args_callback_noarg_add(char short_opt,
+ char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data);
+ EAPI void ecore_config_app_describe(char *description);
+
+ EAPI int ecore_config_create(const char *key, void *val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_typed_create(const char *key, void *val,
+ int type, char short_opt,
+ char *long_opt, char *desc);
+ EAPI int ecore_config_boolean_create(const char *key, int val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_int_create(const char *key, int val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_int_create_bound(const char *key, int val,
+ int low, int high,
+ int step, char short_opt,
+ char *long_opt,
+ char *desc);
+ EAPI int ecore_config_string_create(const char *key, char *val,
+ char short_opt,
+ char *long_opt, char *desc);
+ EAPI int ecore_config_float_create(const char *key, float val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_float_create_bound(const char *key,
+ float val, float low,
+ float high, float step,
+ char short_opt,
+ char *long_opt,
+ char *desc);
+ EAPI int ecore_config_argb_create(const char *key, char *val,
+ char short_opt, char *long_opt,
+ char *desc);
+ EAPI int ecore_config_theme_create(const char *key, char *val,
+ char short_opt, char *long_opt,
+ char *desc);
+
+# ifdef __cplusplus
+}
+# endif
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_ipc \
+-I$(top_srcdir)/ \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_ipc \
+-I$(top_builddir)/ \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@EVAS_CFLAGS@ \
+@EET_CFLAGS@ \
+@EINA_CFLAGS@
+
+CLEANFILES = $(DB)
+
+if BUILD_ECORE_CONFIG
+
+#DB = system.db
+#$(DB): Makefile
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/theme/name str "winter"
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/font/path str "$(pkgdatadir)/data/fonts"
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/browser str `which firefox 2>/dev/null || which phoenix 2>/dev/null || which mozilla 2>/dev/null || which opera 2>/dev/null || which konqueror 2>/dev/null || which epiphany 2>/dev/null`
+# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/email str `which thunderbird 2>/dev/null || which mozilla 2>/dev/null || which kmail 2>/dev/null || which sylpheed 2>/dev/null || which evolution 2>/dev/null`
+
+lib_LTLIBRARIES = libecore_config.la
+
+include_HEADERS = Ecore_Config.h
+
+libecore_config_la_LDFLAGS = -no-undefined -version-info @version_info@ @ecore_config_release_info@
+
+#config_DATA = $(DB)
+#configdir = $(pkgdatadir)
+
+libecore_config_la_SOURCES = \
+ecore_config.c \
+ecore_config_util.c \
+ecore_config_storage.c \
+ecore_config_extra.c \
+ecore_config_db.c
+
+libecore_config_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@EET_LIBS@ \
+@EINA_LIBS@ \
+@EVAS_LIBS@
+
+if BUILD_ECORE_IPC
+
+libecore_config_la_SOURCES += \
+ecore_config_ipc_main.c \
+ecore_config_ipc_ecore.c
+
+libecore_config_la_LIBADD += $(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la
+
+endif
+
+endif
+
+EXTRA_DIST = \
+ecore_config_ipc.h \
+ecore_config_private.h \
+ecore_config_util.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "Ecore_Config.h"
+#include "ecore_config_private.h"
+#include "ecore_config_ipc.h"
+
+#include "ecore_config_util.h"
+int _ecore_config_log_dom = -1;
+int DEBUG = 0;
+EAPI Ecore_Config_Server *__ecore_config_server_global = NULL;
+EAPI Ecore_Config_Server *__ecore_config_server_local = NULL;
+EAPI Ecore_Config_Bundle *__ecore_config_bundle_local = NULL;
+EAPI char *__ecore_config_app_name = NULL;
+int __ecore_config_system_init = 0;
+
+static int _ecore_config_system_init_no_load(void);
+static int _ecore_config_system_load(void);
+
+static inline void *__ecore_argb_to_long(int a, int r, int g, int b, long *v);
+static inline void *__ecore_argbstr_to_long(const char *argb, long *v);
+
+static const char *_ecore_config_type[] =
+ { "undefined", "integer", "float", "string", "colour", "theme", "boolean", "structure" };
+
+/**
+ * @defgroup Ecore_Config_Property_Group Ecore Config Property Functions
+ *
+ * Functions that retrieve or set the attributes relating to a property.
+ */
+
+/**
+ * Removes the given property from the local configuration and destroys it.
+ * @param e Property to destroy.
+ * @return @c NULL
+ * @ingroup Ecore_Config_Property_Group
+ */
+EAPI Ecore_Config_Prop *
+ecore_config_dst(Ecore_Config_Prop * e)
+{
+ Ecore_Config_Bundle *t;
+ Ecore_Config_Prop *p, *c;
+ Ecore_Config_Listener_List *l;
+
+ p = NULL;
+ t = __ecore_config_bundle_local;
+ c = t->data;
+
+ if (!e || !e->key)
+ return NULL;
+ if (t)
+ {
+ if (t->data == e)
+ t->data = e->next;
+ else
+ {
+ do
+ {
+ p = c;
+ c = c->next;
+ }
+ while (c && (c != e));
+ if (c) /* remove from list if even in there */
+ p->next = c->next;
+ }
+ }
+
+ while (e->listeners)
+ {
+ l = e->listeners;
+ e->listeners = e->listeners->next;
+ free(l);
+ }
+
+ if (e->key)
+ free(e->key);
+ if (e->ptr && ((e->type == ECORE_CONFIG_STR) || (e->type == ECORE_CONFIG_THM)))
+ free(e->ptr);
+
+ memset(e, 0, sizeof(Ecore_Config_Prop));
+ free(e);
+
+ return NULL;
+}
+
+/**
+ * @defgroup Ecore_Config_Get_Group Configuration Retrieve Functions
+ *
+ * Functions that retrieve configuration values, based on type.
+ */
+
+/**
+ * Returns the property with the given key.
+ * @param key The unique name of the wanted property.
+ * @return The property that corresponds to the given key. @c NULL if the
+ * key could not be found.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI Ecore_Config_Prop *
+ecore_config_get(const char *key)
+{
+ Ecore_Config_Bundle *t;
+ Ecore_Config_Prop *e;
+
+ t = __ecore_config_bundle_local;
+ if (!t || !key)
+ return NULL;
+ e = t->data;
+ while (e)
+ {
+ if (!strcmp(key, e->key))
+ return e;
+ e = e->next;
+ }
+ return NULL;
+}
+
+/**
+ * Returns the type of the property.
+ * @param e Property to get the type of.
+ * @returns The type of the property. If the property is invalid, then the
+ * string "not found" is returned.
+ * @ingroup Ecore_Config_Property_Group
+ */
+EAPI const char *
+ecore_config_type_get(const Ecore_Config_Prop * e)
+{
+ if (e)
+ {
+ return _ecore_config_type[e->type];
+ }
+ return "not found";
+}
+
+/**
+ * Returns the specified property as a string.
+ * @param key The property key.
+ * @return The string value of the property. The function returns @c NULL if
+ * the property is not a string or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI char *
+ecore_config_string_get(const char *key)
+{
+ return _ecore_config_string_get( ecore_config_get(key) );
+}
+
+char *
+_ecore_config_string_get(Ecore_Config_Prop *e)
+{
+ return (e && (e->type == ECORE_CONFIG_STR) && e->ptr) ? strdup(e->ptr) : NULL;
+}
+
+/**
+ * Returns the specified property as an integer.
+ * @param key The property key.
+ * @return The value of the property. The function returns -1 if the
+ * property is not an integer or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI int
+ecore_config_boolean_get(const char *key)
+{
+ return _ecore_config_boolean_get( ecore_config_get(key) );
+}
+
+int
+_ecore_config_boolean_get(Ecore_Config_Prop *e)
+{
+ return (e && ((e->type == ECORE_CONFIG_INT) || (e->type == ECORE_CONFIG_BLN))) ? (e->val != 0) : -1;
+}
+
+/**
+ * Returns the specified property as a long integer.
+ * @param key The property key.
+ * @return The integer value of the property. The function returns 0 if the
+ * property is not an integer or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI long
+ecore_config_int_get(const char *key)
+{
+ return _ecore_config_int_get( ecore_config_get(key) );
+}
+
+long
+_ecore_config_int_get(Ecore_Config_Prop *e)
+{
+ return (e && ((e->type == ECORE_CONFIG_INT) || (e->type == ECORE_CONFIG_RGB))) ? e->val : 0L;
+}
+
+/**
+ * Returns the specified property as a float.
+ * @param key The property key.
+ * @return The float value of the property. The function returns 0.0 if the
+ * property is not a float or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI float
+ecore_config_float_get(const char *key)
+{
+ return _ecore_config_float_get( ecore_config_get(key) );
+}
+
+float
+_ecore_config_float_get(Ecore_Config_Prop *e)
+{
+ return (e && (e->type == ECORE_CONFIG_FLT)) ? ((float)e->val / ECORE_CONFIG_FLOAT_PRECISION) : 0.0;
+}
+
+/**
+ * Finds the alpha, red, green and blue values of a color property.
+ * @param key The property key.
+ * @param a A pointer to an integer to store the alpha value into.
+ * @param r A pointer to an integer to store the red value into.
+ * @param g A pointer to an integer to store the green value into.
+ * @param b A pointer to an integer to store the blue value into.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL
+ * otherwise.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI int
+ecore_config_argb_get(const char *key, int *a, int *r, int *g, int *b)
+{
+ return _ecore_config_argb_get( ecore_config_get(key), a, r, g, b);
+}
+
+int
+_ecore_config_argb_get(Ecore_Config_Prop *e, int *a, int *r, int *g, int *b)
+{
+ if (e && ((e->type == ECORE_CONFIG_RGB)))
+ {
+ if(a) *a = (e->val >> 24) & 0xff;
+ if(r) *r = (e->val >> 16) & 0xff;
+ if(g) *g = (e->val >> 8) & 0xff;
+ if(b) *b = e->val & 0xff;
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+ return ECORE_CONFIG_ERR_FAIL;
+}
+
+/**
+ * Returns a color property as a long
+ * @param key The property key.
+ * @return ARGB data as long
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI long
+ecore_config_argbint_get(const char *key)
+{
+ return _ecore_config_argbint_get( ecore_config_get(key) );
+}
+
+long
+_ecore_config_argbint_get(Ecore_Config_Prop *e)
+{
+ if (e && ((e->type == ECORE_CONFIG_RGB)))
+ {
+ return e->val;
+ }
+ return 0L;
+}
+
+/**
+ * Returns a color property as a string of hexadecimal characters.
+ * @param key The property key.
+ * @return A string of hexadecimal characters in the format #aarrggbb.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI char *
+ecore_config_argbstr_get(const char *key)
+{
+ return _ecore_config_argbstr_get( ecore_config_get(key) );
+}
+
+char *
+_ecore_config_argbstr_get(Ecore_Config_Prop *e)
+{
+ char *r;
+
+ r = NULL;
+ esprintf(&r, "#%08x", _ecore_config_int_get(e));
+ return r;
+}
+
+/**
+ * Returns a theme property.
+ * @param key The property key.
+ * @return The name of the theme the property refers to. The function returns
+ * @c NULL if the property is not a theme or is not set.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI char *
+ecore_config_theme_get(const char *key)
+{
+ return _ecore_config_theme_get( ecore_config_get(key) );
+}
+
+char *
+_ecore_config_theme_get(Ecore_Config_Prop *e)
+{
+ return (e && (e->type == ECORE_CONFIG_THM)) ? strdup(e->ptr) : NULL;
+}
+
+/**
+ * Retrieves the key as a string.
+ * @param key The property key.
+ * @return Returns a character array in the form of 'key:type=value'. @c NULL
+ * is returned if the property does not exist.
+ * @ingroup Ecore_Config_Get_Group
+ */
+EAPI char *
+ecore_config_as_string_get(const char *key)
+{
+ Ecore_Config_Prop *e;
+ char *val;
+ char *r;
+
+ val = NULL;
+ r = NULL;
+ if (!(e = ecore_config_get(key)))
+ ERR("no such property, \"%s\"...", key);
+ else
+ {
+ switch (e->type)
+ {
+ case ECORE_CONFIG_NIL:
+ val = strdup("<nil>");
+ break;
+ case ECORE_CONFIG_INT:
+ esprintf(&val, "%ld", _ecore_config_int_get(e));
+ break;
+ case ECORE_CONFIG_BLN:
+ esprintf(&val, "%ld", _ecore_config_boolean_get(e));
+ break;
+ case ECORE_CONFIG_FLT:
+ esprintf(&val, "%lf", _ecore_config_float_get(e));
+ break;
+ case ECORE_CONFIG_STR:
+ esprintf(&val, "\"%s\"", _ecore_config_string_get(e));
+ break;
+ case ECORE_CONFIG_RGB:
+ esprintf(&val, "#%08x", _ecore_config_int_get(e));
+ break;
+ case ECORE_CONFIG_THM:
+ esprintf(&val, "\"%s\"", _ecore_config_theme_get(e));
+ break;
+ case ECORE_CONFIG_SCT:
+ break;
+ default:
+ esprintf(&r, "%s:unknown_type", key);
+ break;
+ }
+ if (val)
+ {
+ esprintf(&r, "%s:%s=%s", key, _ecore_config_type[e->type], val);
+ free(val);
+ }
+ }
+ return r;
+}
+
+EAPI int
+ecore_config_bound(Ecore_Config_Prop * e)
+{
+ int ret;
+ long v;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+
+ if (!e)
+ return ECORE_CONFIG_ERR_FAIL;
+ if (e->flags & ECORE_CONFIG_FLAG_BOUNDS)
+ {
+ if ((e->val < e->lo))
+ {
+ WRN("ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...",
+ e->key, e->val, e->lo);
+ e->val = e->lo;
+ }
+ else if ((e->val > e->hi))
+ {
+ WRN("ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...",
+ e->key, e->val, e->hi);
+ e->val = e->hi;
+ }
+ else
+ ret = ECORE_CONFIG_ERR_IGNORED;
+ }
+ else
+ ret = ECORE_CONFIG_ERR_IGNORED;
+
+ if (e->step)
+ {
+ v = ((int)(e->val / e->step)) * e->step;
+ if (v != e->val)
+ {
+ if (e->type == ECORE_CONFIG_FLT)
+ WRN("ecore_config_bound(\"%s\"): float value %f not a multiple of %f, adjusted to %f...",
+ e->key, ((double)e->val) / ECORE_CONFIG_FLOAT_PRECISION,
+ ((double)e->step) / ECORE_CONFIG_FLOAT_PRECISION,
+ ((double)v) / ECORE_CONFIG_FLOAT_PRECISION);
+ else
+ WRN("ecore_config_bound(\"%s\"): integer value %ld not a multiple of %ld, adjusted to %ld...",
+ e->key, e->val, e->step, v);
+ ret = ECORE_CONFIG_ERR_SUCC;
+ e->val = v;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * Tries to guess the type of a property.
+ *
+ * This function first checks to see if the property exists. If it does, then
+ * the type of the stored property is returned. Otherwise, the function tries
+ * to guess the type of the property based on @p val.
+ *
+ * @param key The property key.
+ * @param val The value in string form.
+ * @return The type of the property determined by the function. Note that if
+ * val is @c NULL, @c ECORE_CONFIG_NIL will be returned.
+ */
+EAPI int
+ecore_config_type_guess(const char *key, const char *val)
+{
+ Ecore_Config_Prop *p;
+ char *l;
+
+ l = NULL;
+
+ if (key && (p = ecore_config_get(key)) && p->type != ECORE_CONFIG_NIL)
+ return p->type;
+
+ if (!val)
+ return ECORE_CONFIG_NIL;
+ if (val[0] == '#')
+ return ECORE_CONFIG_RGB;
+ strtol(val, &l, 10);
+ if (*l)
+ {
+ float f;
+
+ if (sscanf(val, "%f%*s", &f) != 1)
+ return ECORE_CONFIG_STR;
+ return ECORE_CONFIG_FLT;
+ }
+ return ECORE_CONFIG_INT;
+}
+
+static int
+ecore_config_typed_val(Ecore_Config_Prop * e, const void *val, int type)
+{
+
+ if (!e)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(val) && (type != ECORE_CONFIG_NIL && type != ECORE_CONFIG_SCT))
+ e->ptr = NULL;
+ else
+ {
+ if (type == ECORE_CONFIG_INT || type == ECORE_CONFIG_BLN)
+ {
+ e->val = (long) *((int *)val);
+ e->type = type;
+ }
+ else if (type == ECORE_CONFIG_STR || type == ECORE_CONFIG_THM)
+ {
+ if (!(e->ptr = strdup(val)))
+ return ECORE_CONFIG_ERR_OOM;
+ if (e->type == ECORE_CONFIG_NIL)
+ e->type = type;
+ }
+ else if (type == ECORE_CONFIG_RGB)
+ {
+ __ecore_argbstr_to_long((char *)val, &e->val);
+ e->type = ECORE_CONFIG_RGB;
+ }
+ else if (type == ECORE_CONFIG_FLT)
+ {
+ e->val = (long) ((*((float *)val)) * ECORE_CONFIG_FLOAT_PRECISION);
+ e->type = ECORE_CONFIG_FLT;
+ }
+ else if (type == ECORE_CONFIG_SCT)
+ {
+ e->type = ECORE_CONFIG_SCT;
+ }
+ else
+ {
+ e->type = ECORE_CONFIG_NIL;
+ }
+
+ ecore_config_bound(e);
+ e->flags |= ECORE_CONFIG_FLAG_MODIFIED;
+ e->flags &= ~ECORE_CONFIG_FLAG_CMDLN;
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+ return ECORE_CONFIG_ERR_IGNORED;
+}
+
+static int
+ecore_config_typed_add(const char *key, const void *val, int type)
+{
+ int error = ECORE_CONFIG_ERR_SUCC;
+ Ecore_Config_Prop *e = NULL;
+ Ecore_Config_Bundle *t;
+
+ t = __ecore_config_bundle_local;
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(e = calloc(1, sizeof(Ecore_Config_Prop))))
+ {
+ return ECORE_CONFIG_ERR_OOM;
+ }
+ else if (!(e->key = strdup(key)))
+ {
+ error = ECORE_CONFIG_ERR_OOM;
+ }
+ else if ((error = ecore_config_typed_val(e, val, type)) == ECORE_CONFIG_ERR_SUCC)
+ {
+ if (t)
+ {
+ e->next = t->data;
+ t->data = e;
+ }
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+
+ if(e->key)
+ free(e->key);
+ if(e)
+ free(e);
+
+ if (error == ECORE_CONFIG_ERR_SUCC)
+ error = ECORE_CONFIG_ERR_FAIL;
+
+ return error;
+}
+
+static int
+ecore_config_add(const char *key, const char *val)
+{
+ int type;
+
+ type = ecore_config_type_guess(key, val);
+ return ecore_config_typed_add(key, val, type);
+}
+
+/**
+ * Sets the description field of the indicated property.
+ * @param key The property key.
+ * @param desc Description string.
+ * @note The description string is copied for the property's use. You can
+ * free @p desc once this function is called.
+ * @ingroup Ecore_Config_Property_Group
+ */
+EAPI int
+ecore_config_describe(const char *key, const char *desc)
+{
+ Ecore_Config_Prop *e;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NODATA;
+ e->description = strdup(desc);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Set the short option character of a property.
+ * @param key The property key.
+ * @param short_opt Character used to indicate the value of a property
+ * given on the command line.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the property does not exist.
+ * @ingroup Ecore_Config_Property_Group
+ */
+EAPI int
+ecore_config_short_opt_set(const char *key, char short_opt)
+{
+ Ecore_Config_Prop *e;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NODATA;
+ e->short_opt = short_opt;
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Set the long option string of the property.
+ * @param key The property key.
+ * @param long_opt String used to indicate the value of a property given
+ * on the command line.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the property does not exist.
+ * @ingroup Ecore_Config_Property_Group
+ */
+EAPI int
+ecore_config_long_opt_set(const char *key, const char *long_opt)
+{
+ Ecore_Config_Prop *e;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NODATA;
+ if (e->long_opt)
+ free(e->long_opt);
+ if (long_opt)
+ e->long_opt = strdup(long_opt);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+static void
+_ecore_config_listener_fire(Ecore_Config_Prop *prop)
+{
+ Ecore_Config_Listener_List *l;
+ for (l = prop->listeners; l; l = l->next)
+ l->listener(prop->key, prop->type, l->tag, l->data);
+
+ /* fire change listeners for the generic struct container etc */
+ if (prop->parent)
+ _ecore_config_listener_fire(prop->parent);
+}
+
+/**
+ * Sets the indicated property to the given value and type.
+ * @param key The property key.
+ * @param val A pointer to the value to set the property to.
+ * @param type The type of the property.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Property_Group
+ */
+EAPI int
+ecore_config_typed_set(const char *key, const void *val, int type)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+/* if (!t) { * global prop *
+ e=ecore_config_get(key);
+ if (e)
+ for(l=e->listeners;l;l=l->next)
+ l->listener(e->key,e->type,l->tag,l->data,t);
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+*/
+ if (!(e = ecore_config_get(key)))
+ return ecore_config_typed_add(key, val, type);
+
+ if ((ret = ecore_config_typed_val(e, val, type)) == ECORE_CONFIG_ERR_SUCC)
+ {
+ _ecore_config_listener_fire(e);
+ }
+ else
+ {
+ ERR("ecore_config_typed_set(\"%s\"): ecore_config_typed_val() failed: %d",
+ key, ret);
+ }
+
+ return ret;
+}
+
+/**
+ * @defgroup Ecore_Config_Set_Group Ecore Config Setters
+ *
+ * Functions that set the value of a property.
+ */
+
+/**
+ * Sets the indicated property to the value indicated by @a val.
+ * @param key The property key.
+ * @param val String representation of value to set.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_set(const char *key, const char *val)
+{
+ int type;
+ int tmpi;
+ float tmpf;
+ long tmpl;
+
+ type = ecore_config_type_guess(key, val);
+ if (type == ECORE_CONFIG_INT || type == ECORE_CONFIG_BLN)
+ {
+ tmpi = atoi(val);
+ return ecore_config_typed_set(key, &tmpi, type);
+ }
+ else if (type == ECORE_CONFIG_FLT)
+ {
+ tmpf = atof(val);
+ return ecore_config_typed_set(key, &tmpf, type);
+ }
+ else if (type == ECORE_CONFIG_RGB)
+ {
+ __ecore_argbstr_to_long(val, &tmpl);
+ return ecore_config_typed_set(key, &tmpl, type);
+ }
+ else
+ return ecore_config_typed_set(key, val, type);
+}
+
+/**
+ * Sets the indicated property to the value given in the string.
+ * @param key The property key.
+ * @param val String representation of the value.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_as_string_set(const char *key, const char *val)
+{
+ return ecore_config_set(key, val);
+}
+
+/**
+ * Sets the indicated property to the given boolean.
+ * @param key The property key.
+ * @param val Boolean integer to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_boolean_set(const char *key, int val)
+{
+ val = val ? 1 : 0;
+ return ecore_config_typed_set(key, &val, ECORE_CONFIG_BLN);
+}
+
+/**
+ * Sets the indicated property to the given integer.
+ * @param key The property key.
+ * @param val Integer to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_int_set(const char *key, int val)
+{
+ return ecore_config_typed_set(key, &val, ECORE_CONFIG_INT);
+}
+
+/**
+ * Sets the indicated property to the given string.
+ * @param key The property key.
+ * @param val String to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_string_set(const char *key, const char *val)
+{
+ return ecore_config_typed_set(key, val, ECORE_CONFIG_STR);
+}
+
+/**
+ * Sets the indicated property to the given float value.
+ * @param key The property key.
+ * @param val Float to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_float_set(const char *key, float val)
+{
+ return ecore_config_typed_set(key, &val, ECORE_CONFIG_FLT);
+}
+
+/**
+ * Sets the indicated property to a color value.
+ * @param key The property key
+ * @param a integer 0..255
+ * @param r integer 0..255
+ * @param g integer 0..255
+ * @param b integer 0..255
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_argb_set(const char *key, int a, int r, int g, int b)
+{
+ long v = 0;
+ return ecore_config_typed_set(key, __ecore_argb_to_long(a,r,g,b, &v), ECORE_CONFIG_RGB);
+}
+
+/**
+ * Sets the indicated property to a color value.
+ * @param key The property key
+ * @param argb ARGB data as long
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_argbint_set(const char *key, long argb)
+{
+ return ecore_config_typed_set(key, &argb, ECORE_CONFIG_RGB);
+}
+
+/**
+ * Sets the indicated property to a color value.
+ * @param key The property key
+ * @param val Color value in ARGB format.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_argbstr_set(const char *key, const char *val)
+{
+ long v = 0;
+ return ecore_config_typed_set(key, __ecore_argbstr_to_long(val, &v), ECORE_CONFIG_RGB);
+}
+
+/**
+ * Sets the indicated property to a theme name.
+ * @param key The property key.
+ * @param val String giving the name of the theme.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_theme_set(const char *key, const char *val)
+{
+ return ecore_config_typed_set(key, val, ECORE_CONFIG_THM);
+}
+
+/**
+ * Sets the theme preview group of an indicated property.
+ * @param key The property key.
+ * @param group The group name.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Set_Group
+ */
+EAPI int
+ecore_config_theme_preview_group_set(const char *key, const char *group)
+{
+ int ret;
+ Ecore_Config_Prop *e;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+ if (!(e = ecore_config_get(key)))
+ { /* prop doesn't exist yet */
+ if ((ret = ecore_config_typed_add(key, "", ECORE_CONFIG_THM)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */
+ return ret; /* ...failed */
+ if (!(e = ecore_config_get(key))) /* get handle */
+ return ECORE_CONFIG_ERR_FAIL;
+ }
+ if (e->data)
+ free(e->data);
+ e->data = strdup(group);
+
+ return ret;
+}
+
+EAPI int
+ecore_config_typed_default(const char *key, const void *val, int type)
+{
+ int ret;
+ Ecore_Config_Prop *e;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+
+ if (!(e = ecore_config_get(key)))
+ { /* prop doesn't exist yet */
+ if ((ret = ecore_config_typed_add(key, val, type)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */
+ return ret; /* ...failed */
+ if (!(e = ecore_config_get(key))) /* get handle */
+ return ECORE_CONFIG_ERR_FAIL;
+ e->flags = e->flags & ~ECORE_CONFIG_FLAG_MODIFIED;
+ }
+ else if (!(e->flags & ECORE_CONFIG_FLAG_MODIFIED) && !(e->flags & ECORE_CONFIG_FLAG_SYSTEM))
+ {
+ ecore_config_typed_set(key, val, type);
+ if (!(e = ecore_config_get(key))) /* get handle */
+ return ECORE_CONFIG_ERR_FAIL;
+ e->flags = e->flags & ~ECORE_CONFIG_FLAG_MODIFIED;
+ }
+ return ret;
+}
+
+/**
+ * @defgroup Ecore_Config_Default_Group Ecore Config Defaults
+ *
+ * Functions that are used to set the default values of properties.
+ */
+
+/**
+ * Sets the indicated property if it has not already been set or loaded.
+ * @param key The property key.
+ * @param val Default value of the key.
+ * @param lo Lowest valid value for the key.
+ * @param hi Highest valid value for the key.
+ * @param step Used by integer and float values.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no errors.
+ * @note The @p lo, @p hi and @p step parameters are only used when storing
+ * integer and float properties.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_default(const char *key, const char *val, float lo, float hi, float step)
+{
+ int ret, type;
+ Ecore_Config_Prop *e;
+
+ type = ecore_config_type_guess(key, val);
+ ret = ecore_config_typed_default(key, val, type);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ if (type == ECORE_CONFIG_INT)
+ {
+ e->step = step;
+ e->flags |= ECORE_CONFIG_FLAG_BOUNDS;
+ e->lo = lo;
+ e->hi = hi;
+ ecore_config_bound(e);
+ }
+ else if (type == ECORE_CONFIG_FLT)
+ {
+ e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION);
+ e->flags |= ECORE_CONFIG_FLAG_BOUNDS;
+ e->lo = (int)(lo * ECORE_CONFIG_FLOAT_PRECISION);
+ e->hi = (int)(hi * ECORE_CONFIG_FLOAT_PRECISION);
+ ecore_config_bound(e);
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * Sets the indicated property to the given boolean if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Boolean Integer to set the value to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_boolean_default(const char *key, int val)
+{
+ val = val ? 1 : 0;
+ return ecore_config_typed_default(key, &val, ECORE_CONFIG_BLN);
+}
+
+/**
+ * Sets the indicated property to the given integer if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Integer to set the value to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_int_default(const char *key, int val)
+{
+ return ecore_config_typed_default(key, &val, ECORE_CONFIG_INT);
+}
+
+/**
+ * Sets the indicated property to the given integer if the property has not yet
+ * been set.
+ *
+ * The bounds and step values are set regardless.
+ *
+ * @param key The property key.
+ * @param val Integer to set the property to.
+ * @param low Lowest valid integer value for the property.
+ * @param high Highest valid integer value for the property.
+ * @param step Increment value for the property.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_int_default_bound(const char *key, int val, int low, int high,
+ int step)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret = ecore_config_typed_default(key, &val, ECORE_CONFIG_INT);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = step;
+ e->flags |= ECORE_CONFIG_FLAG_BOUNDS;
+ e->lo = low;
+ e->hi = high;
+ ecore_config_bound(e);
+ }
+
+ return ret;
+}
+
+/**
+ * Sets the indicated property to the given string if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val String to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_string_default(const char *key, const char *val)
+{
+ return ecore_config_typed_default(key, val, ECORE_CONFIG_STR);
+}
+
+/**
+ * Sets the indicated property to the given float if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Float to set the property to.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_float_default(const char *key, float val)
+{
+ return ecore_config_typed_default(key, &val, ECORE_CONFIG_FLT);
+}
+
+/**
+ * Sets the indicated property to the given float if the property has not yet
+ * been set.
+ *
+ * The bounds and step values are set regardless.
+ *
+ * @param key The property key.
+ * @param val Float to set the property to.
+ * @param low Lowest valid integer value for the property.
+ * @param high Highest valid float value for the property.
+ * @param step Increment value for the property.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_float_default_bound(const char *key, float val, float low,
+ float high, float step)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret = ecore_config_typed_default(key, &val, ECORE_CONFIG_FLT);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION);
+ e->flags |= ECORE_CONFIG_FLAG_BOUNDS;
+ e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION);
+ e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION);
+ ecore_config_bound(e);
+ }
+
+ return ret;
+}
+
+/**
+ * Sets the indicated property to a color value if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param a integer 0..255
+ * @param r integer 0..255
+ * @param g integer 0..255
+ * @param b integer 0..255
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_argb_default(const char *key, int a, int r, int g, int b)
+{
+ long v = 0;
+ return ecore_config_typed_default(key, __ecore_argb_to_long(a,r,g,b, &v), ECORE_CONFIG_RGB);
+}
+
+/**
+ * Sets the indicated property to a color value if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param argb ARGB data as long
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_argbint_default(const char *key, long argb)
+{
+ return ecore_config_typed_default(key, &argb, ECORE_CONFIG_RGB);
+}
+
+/**
+ * Sets the indicated property to a color value if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val Color value in ARGB format.
+ * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_argbstr_default(const char *key, const char *val)
+{
+ long v = 0;
+ return ecore_config_typed_default(key, __ecore_argbstr_to_long(val, &v), ECORE_CONFIG_RGB);
+}
+
+/**
+ * Sets the indicated property to a theme name if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @param val String giving the name of the theme.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Default_Group
+ */
+EAPI int
+ecore_config_theme_default(const char *key, const char *val)
+{
+ return ecore_config_typed_default(key, val, ECORE_CONFIG_THM);
+}
+
+/**
+ * @defgroup Ecore_Config_Struct_Group Ecore Config Structures
+ *
+ * Functions that are used to create structures of properties.
+ */
+
+/**
+ * Sets the indicated property to a structure if the property has not yet
+ * been set.
+ * @param key The property key.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_create(const char *key)
+{
+ WRN("you are using ecore_config structures. These are very young");
+ WRN(" and not complete - you have been warned");
+
+ return ecore_config_typed_default(key, NULL, ECORE_CONFIG_SCT);
+}
+
+static int
+_ecore_config_struct_append(Ecore_Config_Prop *sct, Ecore_Config_Prop *add)
+{
+ Eina_List *l;
+
+ if (!sct || !add || sct->type != ECORE_CONFIG_SCT)
+ return ECORE_CONFIG_ERR_IGNORED;
+
+ l = sct->data;
+ sct->data = eina_list_append(l, add);
+ add->parent = sct;
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+static int
+_ecore_config_struct_typed_add(const char *key, const char *name, const void *val,
+ int type)
+{
+ char *subkey;
+ int ret;
+
+ subkey = malloc((strlen(key) + strlen(name) + 2) * sizeof(char));
+ strcpy(subkey, key);
+ strcat(subkey, ".");
+ strcat(subkey, name);
+
+ ecore_config_typed_default(subkey, val, type);
+ ret = _ecore_config_struct_append(ecore_config_get(key),
+ ecore_config_get(subkey));
+ free(subkey);
+ return ret;
+}
+
+/**
+ * Add an int property to the named structure. The property is set if it has not
+ * yet been set.
+ * @param key The key of the structure to add to.
+ * @param name The name of the item to add - this will be appended to the key
+ * @param val the int to default to
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_int_add(const char *key, const char *name, int val)
+{
+ return _ecore_config_struct_typed_add(key, name, &val, ECORE_CONFIG_INT);
+}
+
+/**
+ * Add a float property to the named structure. The property is set if it has
+ * not yet been set.
+ * @param key The key of the structure to add to.
+ * @param name The name of the item to add - this will be appended to the key
+ * @param val The float to default to
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_float_add(const char *key, const char *name, float val)
+{
+ return _ecore_config_struct_typed_add(key, name, &val, ECORE_CONFIG_FLT);
+}
+
+/**
+ * Add a string property to the named structure. The property is set if it has
+ * not yet been set.
+ * @param key The key of the structure to add to.
+ * @param name The name of the item to add - this will be appended to the key
+ * @param val The string to default to
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_string_add(const char *key, const char *name, const char* val)
+{
+ return _ecore_config_struct_typed_add(key, name, val, ECORE_CONFIG_STR);
+}
+
+/**
+ * Add an argb property to the named structure. The property is set if it has
+ * not yet been set.
+ * @param key The key of the structure to add to.
+ * @param name The name of the item to add - this will be appended to the key
+ * @param a The alpha to default to
+ * @param r The red to default to
+ * @param g The green to default to
+ * @param b The blue to default to
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_argb_add(const char *key, const char *name, int a, int r,
+ int g, int b)
+{
+ long argb;
+
+ __ecore_argb_to_long(a, r, g, b, &argb);
+ return _ecore_config_struct_typed_add(key, name, &argb, ECORE_CONFIG_RGB);
+}
+
+/**
+ * Add a theme property to the named structure. The property is set if it has
+ * not yet been set.
+ * @param key The key of the structure to add to.
+ * @param name The name of the item to add - this will be appended to the key
+ * @param val The theme name to default to
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_theme_add(const char *key, const char *name, const char* val)
+{
+ return _ecore_config_struct_typed_add(key, name, val, ECORE_CONFIG_THM);
+}
+
+/**
+ * Add a boolean property to the named structure. The property is set if it has
+ * not yet been set.
+ * @param key The key of the structure to add to.
+ * @param name The name of the item to add - this will be appended to the key
+ * @param val The boolean to default to
+ * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_boolean_add(const char *key, const char *name, int val)
+{
+ val = val ? 1 : 0;
+ return _ecore_config_struct_typed_add(key, name, &val, ECORE_CONFIG_BLN);
+}
+
+/**
+ * Get the contents of a defined structure property and load it into the passed
+ * C struct
+ * @param key The name of the structure property to look up.
+ * @param data The struct to write into.
+ * @return @c ECORE_CONFIG_ERR_SUCC if the structure is written successfully.
+ * @ingroup Ecore_Config_Struct_Group
+ */
+EAPI int
+ecore_config_struct_get(const char *key, void *data)
+{
+ Ecore_Config_Prop *e, *f;
+ Eina_List *l;
+ unsigned char *ptr;
+ long argb;
+
+ e = ecore_config_get(key);
+ if (!e)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ l = e->data;
+ ptr = data;
+ while (l)
+ {
+ f = (Ecore_Config_Prop *) l->data;
+ switch (f->type)
+ {
+ case ECORE_CONFIG_INT:
+ *((int *) ptr) = _ecore_config_int_get(f);
+ ptr += sizeof(int);
+ break;
+ case ECORE_CONFIG_BLN:
+ *((int *) ptr) = _ecore_config_boolean_get(f);
+ ptr += sizeof(int);
+ break;
+ case ECORE_CONFIG_FLT:
+ *((float *) ptr) = _ecore_config_float_get(f);
+ ptr += sizeof(float);
+ break;
+ case ECORE_CONFIG_STR:
+ case ECORE_CONFIG_THM:
+ *((char **) ptr) = _ecore_config_string_get(f);
+ ptr += sizeof(char *);
+ break;
+ case ECORE_CONFIG_RGB:
+ argb = _ecore_config_argbint_get(f);
+ *((int *) ptr) = (argb >> 24) & 0xff;
+ ptr += sizeof(int);
+ *((int *) ptr) = (argb >> 16) & 0xff;
+ ptr += sizeof(int);
+ *((int *) ptr) = (argb >> 8) & 0xff;
+ ptr += sizeof(int);
+ *((int *) ptr) = argb & 0xff;
+ ptr += sizeof(int);
+ break;
+ default:
+ WRN("ARGH - STRUCT coding not implemented yet");
+ }
+ l = eina_list_next(l);
+ }
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * @defgroup Ecore_Config_Listeners_Group Ecore Config Listeners
+ *
+ * Functions that set and unset property listener callbacks.
+ */
+
+/**
+ * Adds a callback function to the list of functions called when a property
+ * changes.
+ * @param name Name of the callback.
+ * @param key The key of the property to listen to.
+ * @param listener Listener callback function.
+ * @param tag Tag to pass to @p listener when it is called.
+ * @param data Data to pass to @p listener when it is called.
+ * @return @c ECORE_CONFIG_ERR_SUCC if successful in setting up the callback.
+ * @ingroup Ecore_Config_Listeners_Group
+ */
+EAPI int
+ecore_config_listen(const char *name, const char *key,
+ Ecore_Config_Listener listener, int tag, void *data)
+{
+ Ecore_Config_Prop *e;
+ Ecore_Config_Listener_List *l;
+
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(e = ecore_config_get(key)))
+ {
+ int ret = ecore_config_add(key, "");
+
+ if (ret != ECORE_CONFIG_ERR_SUCC)
+ {
+ ERR("ecore_config_listen: ecore_config_add(\"%s\") failed: %d",
+ key, ret);
+ return ret;
+ }
+ if (!(e = ecore_config_get(key)))
+ {
+ ERR("ecore_config_listen: list of properties corrupted!?");
+ return ECORE_CONFIG_ERR_FAIL;
+ }
+ }
+
+ for (l = e->listeners; l; l = l->next)
+ if (!strcmp(l->name, name) || (l->listener == listener))
+ {
+ ERR("ecore_config_listen: %s is already listening for changes of %s...",
+ name, key);
+ return ECORE_CONFIG_ERR_IGNORED;
+ }
+
+ if (!(l = malloc(sizeof(Ecore_Config_Listener_List))))
+ return ECORE_CONFIG_ERR_OOM;
+
+ ERR("registering listener \"%s\" for \"%s\" (%d)...", name, key, e->type);
+
+ memset(l, 0, sizeof(Ecore_Config_Listener_List));
+
+ l->listener = listener;
+ l->name = name;
+ l->data = data;
+ l->tag = tag;
+ l->next = e->listeners;
+ e->listeners = l;
+
+ if (e->type != ECORE_CONFIG_NIL) /* call right on creation if prop exists and has val */
+ listener(key, e->type, tag, data);
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Removes a listener callback.
+ * @param name Name of the callback to remove.
+ * @param key The property key the callback is listening to.
+ * @param listener The callback function to remove.
+ * @return @c ECORE_CONFIG_ERR_SUCC if successful in removing the callback.
+ * If no callback matches the given parameters, then
+ * @c ECORE_CONFIG_ERR_NOTFOUND is returned. If @c NULL is passed
+ * for the key pointer, @c ECORE_CONFIG_ERR_NODATA is returned.
+ * @ingroup Ecore_Config_Listeners_Group
+ */
+EAPI int
+ecore_config_deaf(const char *name, const char *key,
+ Ecore_Config_Listener listener)
+{
+ Ecore_Config_Prop *e;
+ Ecore_Config_Listener_List *l, *p;
+ int ret;
+
+ ret = ECORE_CONFIG_ERR_NOTFOUND;
+
+ if (!key)
+ return ECORE_CONFIG_ERR_NODATA;
+
+ if (!(e = ecore_config_get(key)))
+ return ECORE_CONFIG_ERR_NOTFOUND;
+
+ for (p = NULL, l = e->listeners; l; p = l)
+ {
+ Ecore_Config_Listener_List *nl;
+
+ nl = l->next;
+ if ((name && !strcmp(l->name, name)) || (l->listener == listener))
+ {
+ ret = ECORE_CONFIG_ERR_SUCC;
+ if (!p)
+ e->listeners = e->listeners->next;
+ else
+ p->next = l->next;
+ memset(l, 0, sizeof(Ecore_Config_Listener));
+ free(l);
+ }
+ l = nl;
+ }
+
+ return ret;
+}
+
+/**
+ * Locates the first configuration bundle on the given server.
+ * @param srv The configuration server.
+ * @return Pointer to the first configuration bundle.
+ */
+EAPI Ecore_Config_Bundle *
+ecore_config_bundle_1st_get(Ecore_Config_Server * srv)
+{ /* anchor: global, but read-only */
+ return srv->bundles;
+}
+
+/**
+ * Locates the configuration bundle after the given one.
+ * @param ns The configuration bundle.
+ * @return The next configuration bundle.
+ */
+EAPI Ecore_Config_Bundle *
+ecore_config_bundle_next_get(Ecore_Config_Bundle * ns)
+{
+ return ns ? ns->next : NULL;
+}
+
+/**
+ * Locates a configuration bundle on a configuration server based on its serial
+ * number.
+ * @param srv The configuration server.
+ * @param serial Serial number.
+ * @return The configuration bundle with the given serial number.
+ */
+EAPI Ecore_Config_Bundle *
+ecore_config_bundle_by_serial_get(Ecore_Config_Server * srv, long serial)
+{
+ Ecore_Config_Bundle *eb;
+
+ eb = srv->bundles;
+
+ if (serial < 0)
+ return NULL;
+ else if (serial == 0)
+ {
+ Ecore_Config_Bundle *r = eb;
+
+ return r;
+ }
+
+ while (eb)
+ {
+ if (eb->serial == serial)
+ return eb;
+ eb = eb->next;
+ }
+ return NULL;
+}
+
+/**
+ * Gets the Ecore_Config_Bundle with the given identifier from the given
+ * server.
+ * @param srv The configuration server.
+ * @param label The bundle's identifier string.
+ * @return The bundle with the given identifier string, or @c NULL if it
+ * could not be found.
+ */
+EAPI Ecore_Config_Bundle *
+ecore_config_bundle_by_label_get(Ecore_Config_Server * srv, const char *label)
+{
+ Ecore_Config_Bundle *ns;
+
+ ns = srv->bundles;
+
+ while (ns)
+ {
+ if (ns->identifier && !strcmp(ns->identifier, label))
+ return ns;
+ ns = ns->next;
+ }
+ return NULL;
+}
+
+/**
+ * Retrieves the bundle's serial number.
+ * @param ns The configuration bundle.
+ * @return The bundle's identifier string, or -1 if ns is @c NULL.
+ */
+EAPI long
+ecore_config_bundle_serial_get(Ecore_Config_Bundle * ns)
+{
+ return ns ? ns->serial : -1;
+}
+
+/**
+ * Retrieves the bundle's identifier.
+ * @param ns The configuration bundle.
+ * @return The bundle's identifer string.
+ */
+EAPI char *
+ecore_config_bundle_label_get(Ecore_Config_Bundle * ns)
+{
+ return ns ? ns->identifier : NULL;
+}
+
+/**
+ * Creates a new Ecore_Config_Bundle.
+ * @param srv Config server.
+ * @param identifier Identifier string for the new bundle.
+ * @return A pointer to a new Ecore_Config_Bundle. @c NULL is returned if the
+ * structure couldn't be allocated.
+ */
+EAPI Ecore_Config_Bundle *
+ecore_config_bundle_new(Ecore_Config_Server * srv, const char *identifier)
+{
+ Ecore_Config_Bundle *t;
+ static long ss;
+
+ ss = 0; /* bundle unique serial */
+
+ if ((t = malloc(sizeof(Ecore_Config_Bundle))))
+ {
+ memset(t, 0, sizeof(Ecore_Config_Bundle));
+
+ t->identifier = (char *)identifier;
+ t->serial = ++ss;
+ t->owner = srv->name;
+ t->next = srv->bundles;
+ srv->bundles = t;
+ }
+ return t;
+}
+
+static Ecore_Config_Server *
+do_init(const char *name)
+{
+ return _ecore_config_ipc_init(name);
+}
+
+static Ecore_Config_Server *
+ecore_config_init_local(const char *name)
+{
+ char *p;
+ char *buf;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ if (!(buf = malloc(PATH_MAX * sizeof(char))))
+ return NULL;
+ snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name);
+ unlink(buf);
+
+ free(buf);
+ }
+
+ return do_init(name);
+}
+
+static Ecore_Config_Server *
+ecore_config_init_global(const char *name)
+{
+ char *p;
+ int global;
+ char *buf;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ if (!(buf = malloc(PATH_MAX * sizeof(char))))
+ return NULL;
+ snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name);
+ global = creat(buf, S_IRWXU);
+
+ if (global)
+ close(global);
+
+ free(buf);
+ }
+
+ return do_init(name);
+}
+
+/**
+ * @defgroup Ecore_Config_App_Lib_Group Ecore Config App Library Functions
+ *
+ * Functions that are used to start up and shutdown the Enlightened
+ * Property Library when used directly by an application.
+ */
+
+/**
+ * Initializes the Enlightened Property Library.
+ *
+ * Either this function or @ref ecore_config_system_init must be run
+ * before any other function in the Enlightened Property Library, even
+ * if you have run @ref ecore_init . The name given is used to
+ * determine the default configuration to load.
+ *
+ * @param name Application name
+ * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up.
+ * @c ECORE_CONFIG_ERR_FAIL otherwise.
+ * @ingroup Ecore_Config_App_Lib_Group
+ */
+EAPI int
+ecore_config_init(const char *name)
+{
+ char *path;
+ Ecore_Config_Prop *list;
+ _ecore_config_log_dom = eina_log_domain_register("EcoreConfig", ECORE_CONFIG_DEFAULT_LOG_COLOR);
+ if(_ecore_config_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the Ecore config module.");
+ return -1;
+ }
+ _ecore_config_system_init_no_load();
+
+ __ecore_config_app_name = strdup(name);
+ __ecore_config_server_local = ecore_config_init_local(name);
+ if (!__ecore_config_server_local)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ list = __ecore_config_bundle_local->data;
+ free( __ecore_config_bundle_local );
+ __ecore_config_bundle_local =
+ ecore_config_bundle_new(__ecore_config_server_local, "config");
+ __ecore_config_bundle_local->data = list;
+
+ path = ecore_config_theme_default_path_get();
+ ecore_config_string_default("/e/themes/search_path", path);
+ if (path)
+ free(path);
+
+ list = ecore_config_get("/e/themes/search_path");
+ if (list)
+ {
+ list->flags |= ECORE_CONFIG_FLAG_SYSTEM;
+ list->flags &= ~ECORE_CONFIG_FLAG_MODIFIED;
+ }
+
+ return _ecore_config_system_load();
+}
+
+/**
+ * Frees memory and shuts down the library for an application.
+ * @return @c ECORE_CONFIG_ERR_IGNORED .
+ * @ingroup Ecore_Config_App_Lib_Group
+ */
+EAPI int
+ecore_config_shutdown(void)
+{
+ return ecore_config_system_shutdown();
+}
+
+/**
+ * @defgroup Ecore_Config_Lib_Lib_Group Ecore Config Library Functions
+ *
+ * Functions that are used to start up and shutdown the Enlightened
+ * Property Library when used directly by an application.
+ */
+
+/**
+ * Initializes the Enlightened Property Library.
+ *
+ * This function is meant to be run from other programming libraries.
+ * It should not be called from applications.
+ *
+ * This function (or @ref ecore_config_init )
+ * must be run before any other function in the
+ * Enlightened Property Library, even if you have run @ref ecore_init .
+ *
+ * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up.
+ * @c ECORE_CONFIG_ERR_FAIL otherwise.
+ * @ingroup Ecore_Config_Lib_Lib_Group
+ */
+EAPI int
+ecore_config_system_init(void)
+{
+ _ecore_config_system_init_no_load();
+ return _ecore_config_system_load();
+}
+
+static int
+_ecore_config_system_init_no_load(void)
+{
+ char *p;
+
+ __ecore_config_system_init++;
+ if (__ecore_config_system_init > 1)
+ return ECORE_CONFIG_ERR_IGNORED;
+
+ DEBUG = -1;
+ if ((p = getenv("ECORE_CONFIG_DEBUG")) && p[0] != 0)
+ {
+ DEBUG = atoi(p);
+ }
+
+ __ecore_config_server_global =
+ ecore_config_init_global(ECORE_CONFIG_GLOBAL_ID);
+ if (!__ecore_config_server_global)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ __ecore_config_bundle_local =
+ ecore_config_bundle_new(__ecore_config_server_global, "system");
+
+ /* set up a simple default path */
+ ecore_config_string_default("/e/themes/search_path", PACKAGE_DATA_DIR "../ewl/themes");
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+
+static int
+_ecore_config_system_load(void)
+{
+ char *buf, *p;
+ Ecore_Config_Prop *sys;
+
+ if (__ecore_config_system_init != 1)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ if ((buf = malloc(PATH_MAX * sizeof(char))))
+ {
+ snprintf(buf, PATH_MAX, "%s/.e/config.eet", p);
+ if (ecore_config_file_load(buf) != 0) {
+ /* even if this file (system.eet) dosen't exist we can
+ * continue without it as it isn't striclty necessary.
+ */
+ ecore_config_file_load(PACKAGE_DATA_DIR "/system.eet");
+ }
+ sys = __ecore_config_bundle_local->data;
+ while (sys)
+ {
+ /* unmark it modified - modification will mean it has been overridden */
+ sys->flags &= ~ECORE_CONFIG_FLAG_MODIFIED;
+ /* mark as system so that examine can hide them */
+ sys->flags |= ECORE_CONFIG_FLAG_SYSTEM;
+ sys = sys->next;
+ }
+ }
+ free(buf);
+ }
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+
+/**
+ * Frees memory and shuts down the library for other programming libraries.
+ * @return @c ECORE_CONFIG_ERR_IGNORED
+ * @ingroup Ecore_Config_Lib_Lib_Group
+ */
+EAPI int
+ecore_config_system_shutdown(void)
+{
+ int ret;
+
+ __ecore_config_system_init--;
+ if (__ecore_config_system_init > 0)
+ return ECORE_CONFIG_ERR_IGNORED;
+
+ ret = _ecore_config_ipc_exit();
+ if (__ecore_config_app_name)
+ free(__ecore_config_app_name);
+ while(__ecore_config_bundle_local->data)
+ ecore_config_dst(__ecore_config_bundle_local->data);
+ free(__ecore_config_bundle_local);
+ free(__ecore_config_server_local);
+ free(__ecore_config_server_global);
+ eina_log_domain_unregister(_ecore_config_log_dom);
+ _ecore_config_log_dom = -1;
+ return ret;
+}
+
+static inline void *
+__ecore_argb_to_long(int a, int r, int g, int b, long *v)
+{
+ *v = ((a << 24) & 0xff000000 )
+ | ((r << 16) & 0xff0000 )
+ | ((g << 8) & 0xff00 )
+ | ( b & 0xff );
+
+ return v;
+}
+
+static inline void *
+__ecore_argbstr_to_long(const char *argb, long *v)
+{
+ char *l = NULL;
+
+ // convert hexadecimal string #..., #0x..., 0x..., ... to long
+ if(*argb == '#')
+ argb++;
+ *v = (long)strtoul( argb, &l, 16);
+
+ if(*l)
+ {
+ ERR("ecore_config_val: value \"%s\" not a valid hexadecimal RGB value?", argb);
+ return NULL;
+ }
+
+ return v;
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <locale.h>
+
+#include <Eet.h>
+
+#include "Ecore_Config.h"
+#include "ecore_config_private.h"
+#include "ecore_config_util.h"
+
+struct _Ecore_Config_DB_File
+{
+ Eet_File *ef;
+};
+
+Ecore_Config_DB_File *
+_ecore_config_db_open_read(const char *file)
+{
+ Eet_File *ef;
+ Ecore_Config_DB_File *db;
+
+ eet_init();
+ db = malloc(sizeof(Ecore_Config_DB_File));
+ if (!db) return NULL;
+ ef = eet_open((char*)file, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ free(db);
+ return NULL;
+ }
+ db->ef = ef;
+ return db;
+}
+
+Ecore_Config_DB_File *
+_ecore_config_db_open_write(const char *file)
+{
+ Eet_File *ef;
+ Ecore_Config_DB_File *db;
+
+ eet_init();
+ db = malloc(sizeof(Ecore_Config_DB_File));
+ if (!db) return NULL;
+ ef = eet_open((char*)file, EET_FILE_MODE_WRITE);
+ if (!ef)
+ {
+ free(db);
+ return NULL;
+ }
+ db->ef = ef;
+ return db;
+}
+
+void
+_ecore_config_db_close(Ecore_Config_DB_File *db)
+{
+ eet_close(db->ef);
+ free(db);
+ eet_shutdown();
+}
+
+char **
+_ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret)
+{
+ char **keys;
+ int key_count;
+ int i;
+
+ keys = eet_list(db->ef, (char*)"*", &key_count);
+ if (!keys)
+ {
+ *num_ret = 0;
+ return NULL;
+ }
+ /* make keys freeable - this is safe to do */
+ for (i = 0; i < key_count; i++) keys[i] = strdup(keys[i]);
+ *num_ret = key_count;
+ return keys;
+}
+
+Ecore_Config_Type
+_ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key)
+{
+ char *data;
+ int size;
+
+ data = eet_read(db->ef, (char*)key, &size);
+ if (data)
+ {
+ if (size <= 2)
+ {
+ free(data);
+ return ECORE_CONFIG_NIL;
+ }
+ if (data[size - 1] != 0)
+ {
+ free(data);
+ return ECORE_CONFIG_NIL;
+ }
+ return (Ecore_Config_Type) data[0];
+ }
+ return ECORE_CONFIG_NIL;
+}
+
+int
+_ecore_config_db_read(Ecore_Config_DB_File *db, const char *key)
+{
+ char *data, *value;
+ int size;
+ Ecore_Config_Type type;
+
+ data = eet_read(db->ef, (char*)key, &size);
+ if (data)
+ {
+ int l;
+ char *prev_locale;
+
+ if (size <= 2)
+ {
+ free(data);
+ return 0;
+ }
+ if (data[size - 1] != 0)
+ {
+ free(data);
+ return 0;
+ }
+ /* "type" NIL 1242 NIL */
+ l = strlen(data);
+ if (l >= (size - 1))
+ {
+ free(data);
+ return 0;
+ }
+
+ type = data[0];
+ value = data + l + 1;
+
+ switch (type)
+ {
+ case ECORE_CONFIG_INT:
+ case ECORE_CONFIG_BLN:
+ {
+ int tmp;
+ prev_locale = setlocale(LC_NUMERIC, "C");
+ tmp = atoi(value);
+ if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+
+ ecore_config_typed_set(key, (void *)&tmp, type);
+ break;
+ }
+ case ECORE_CONFIG_FLT:
+ {
+ float tmp;
+ prev_locale = setlocale(LC_NUMERIC, "C");
+ tmp = atof(value);
+ if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+
+ ecore_config_typed_set(key, (void *)&tmp, type);
+ break;
+ }
+ case ECORE_CONFIG_RGB:
+ ecore_config_argbstr_set(key, value);
+ break;
+ case ECORE_CONFIG_STR:
+ case ECORE_CONFIG_THM:
+ ecore_config_typed_set(key, (void *)value, type);
+ break;
+ case ECORE_CONFIG_SCT:
+ INF("loading struct %s", key);
+ break;
+ default:
+ WRN("Type %d not handled", type);
+ }
+ free(data);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+void *
+_ecore_config_db_key_data_get(Ecore_Config_DB_File *db, const char *key, int *size_ret)
+{
+ char *data;
+ int size;
+
+ data = eet_read(db->ef, (char*)key, &size);
+ if (data)
+ {
+ int l;
+ char *dat;
+
+ if (size <= 2)
+ {
+ free(data);
+ return NULL;
+ }
+ if (data[size - 1] != 0)
+ {
+ free(data);
+ return NULL;
+ }
+ * "type" NIL data_goes_here NIL *
+ l = strlen(data);
+ if (l >= (size - 1))
+ {
+ free(data);
+ return NULL;
+ }
+ dat = malloc(size - (l + 2));
+ memcpy(dat, data + l + 1, size - (l + 2));
+ free(data);
+ *size_ret = size - (l + 2);
+ return dat;
+ }
+ return NULL;
+}*/
+
+void
+_ecore_config_db_write(Ecore_Config_DB_File *db, Ecore_Config_Prop *e)
+{
+ char *prev_locale= NULL;
+ char *val = NULL;
+ char *r = NULL;
+ int num;
+
+ prev_locale = setlocale(LC_NUMERIC, "C");
+
+ switch (e->type)
+ {
+ case ECORE_CONFIG_INT:
+ esprintf(&val, "%i", _ecore_config_int_get(e));
+ break;
+ case ECORE_CONFIG_BLN:
+ esprintf(&val, "%i", _ecore_config_boolean_get(e));
+ break;
+ case ECORE_CONFIG_FLT:
+ esprintf(&val, "%16.16f", _ecore_config_float_get(e));
+ break;
+ case ECORE_CONFIG_STR:
+ val = _ecore_config_string_get(e);
+ break;
+ case ECORE_CONFIG_THM:
+ val = _ecore_config_theme_get(e);
+ break;
+ case ECORE_CONFIG_RGB:
+ val = _ecore_config_argbstr_get(e);
+ break;
+ default:
+ WRN("Type %d not handled", e->type);
+ }
+
+ if (prev_locale)
+ {
+ setlocale(LC_NUMERIC, prev_locale);
+ }
+
+ if(val)
+ {
+ num = esprintf(&r, "%c%c%s%c", (char) e->type, 0, val, 0);
+ if(num)
+ eet_write(db->ef, e->key, r, num, 1);
+ free(r);
+ }
+
+ free(val);
+}
+/*
+void
+_ecore_config_db_key_data_set(Ecore_Config_DB_File *db, const char *key, void *data, int data_size)
+{
+ char *buf;
+ int num;
+
+ num = 1 + 1 + data_size + 1;
+ buf = malloc(num);
+ if (!buf) return;
+ buf[0] = (char) ECORE_CONFIG_BIN;
+ buf[1] = 0;
+ memcpy(buf + 2, data, data_size);
+ buf[num - 1] = 0;
+ eet_write(db->ef, (char*)key, buf, num, 1);
+ free(buf);
+}*/
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "Ecore_Config.h"
+#include "Ecore.h"
+#include "ecore_config_private.h"
+typedef struct __Ecore_Config_Arg_Callback _Ecore_Config_Arg_Callback;
+struct __Ecore_Config_Arg_Callback
+{
+ char short_opt;
+ char *long_opt;
+ char *description;
+ void *data;
+ void (*func)(char *val, void *data);
+ Ecore_Config_Type type;
+ _Ecore_Config_Arg_Callback *next;
+};
+
+char *__ecore_config_app_description;
+_Ecore_Config_Arg_Callback *_ecore_config_arg_callbacks;
+
+/* shorthand prop setup code to make client apps a little smaller ;) */
+
+/**
+ * Creates a new property, if it does not already exist, and sets its
+ * attributes to those given.
+ *
+ * The type of the property is guessed from the key and the value
+ * given.
+ *
+ * @param key The property key.
+ * @param val Pointer to default value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_create(const char *key, void *val, char short_opt, char *long_opt,
+ char *desc)
+{
+ int type = ecore_config_type_guess(key, val);
+
+ return ecore_config_typed_create(key, val, type, short_opt, long_opt, desc);
+}
+
+/**
+ * Creates a new property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Pointer to default value of key.
+ * @param type Type of the property.
+ * @param short_opt Short option used to set the property from
+ * command line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_typed_create(const char *key, void *val, int type, char short_opt,
+ char *long_opt, char *desc)
+{
+ int ret;
+
+ if ((ret =
+ ecore_config_typed_default(key, val, type)) != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ if ((ret =
+ ecore_config_short_opt_set(key, short_opt)) != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ if ((ret =
+ ecore_config_long_opt_set(key, long_opt)) != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ ret = ecore_config_describe(key, desc);
+ return ret;
+}
+
+/**
+ * Creates a new boolean property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default boolean value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_boolean_create(const char *key, int val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_BLN, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new integer property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default integer value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_int_create(const char *key, int val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_INT, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new integer property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default integer value of key.
+ * @param low Lowest valid integer value for the property.
+ * @param high Highest valid integer value for the property.
+ * @param step Increment value for the property.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_int_create_bound(const char *key, int val, int low, int high,
+ int step, char short_opt, char *long_opt,
+ char *desc)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret =
+ ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_INT, short_opt, long_opt,
+ desc);
+ if (ret != ECORE_CONFIG_ERR_SUCC)
+ return ret;
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = step;
+ e->flags |= ECORE_CONFIG_FLAG_BOUNDS;
+ e->lo = low;
+ e->hi = high;
+ ecore_config_bound(e);
+ }
+ return ret;
+}
+
+/**
+ * Creates a new string property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_string_create(const char *key, char *val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_STR, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new float property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default float value of key.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_float_create(const char *key, float val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_FLT, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new float property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default float value of key.
+ * @param low Lowest valid float value for the property.
+ * @param high Highest valid float value for the property.
+ * @param step Increment value for the property.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_float_create_bound(const char *key, float val, float low,
+ float high, float step, char short_opt,
+ char *long_opt, char *desc)
+{
+ Ecore_Config_Prop *e;
+ int ret;
+
+ ret =
+ ecore_config_typed_create(key, (void *)&val, ECORE_CONFIG_FLT, short_opt, long_opt,
+ desc);
+ e = ecore_config_get(key);
+ if (e)
+ {
+ e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION);
+ e->flags |= ECORE_CONFIG_FLAG_BOUNDS;
+ e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION);
+ e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION);
+ ecore_config_bound(e);
+ }
+ return ret;
+}
+
+/**
+ * Creates a new color property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default color value of key, as a hexadecimal string.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_argb_create(const char *key, char *val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_RGB, short_opt, long_opt,
+ desc);
+}
+
+/**
+ * Creates a new theme property, if it does not already exist, and sets its
+ * attributes to those given.
+ * @param key The property key.
+ * @param val Default theme name for the property.
+ * @param short_opt Short option used to set the property from command
+ * line.
+ * @param long_opt Long option used to set the property from command line.
+ * @param desc String description of property.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success.
+ * @ingroup Ecore_Config_Create_Group
+ */
+int
+ecore_config_theme_create(const char *key, char *val, char short_opt,
+ char *long_opt, char *desc)
+{
+ return
+ ecore_config_typed_create(key, (void *)val, ECORE_CONFIG_THM, short_opt, long_opt,
+ desc);
+}
+
+/* this should only be built if evas is present */
+
+/**
+ * Calls evas_font_path_append on @p evas for each of the font names stored
+ * in the property "/e/font/path".
+ * @param evas Evas object to append the font names to.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the property has not been set.
+ */
+int
+ecore_config_evas_font_path_apply(Evas * evas)
+{
+ char *font_path, *font_path_tmp, *ptr, *end;
+
+ font_path = ecore_config_string_get("/e/font/path");
+
+ if (!font_path)
+ return ECORE_CONFIG_ERR_NODATA;
+ ptr = font_path;
+ end = font_path + strlen(font_path);
+ font_path_tmp = font_path;
+ while (ptr && ptr < end)
+ {
+ while (*ptr != '|' && ptr < end)
+ ptr++;
+ if (ptr < end)
+ *ptr = '\0';
+
+ evas_font_path_append(evas, font_path_tmp);
+ ptr++;
+ font_path_tmp = ptr;
+ }
+
+ free(font_path);
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/**
+ * Retrieves the default theme search path.
+ *
+ * @return The default theme search path.
+ */
+char *
+ecore_config_theme_default_path_get(void)
+{
+ char *path, *home;
+ int len;
+
+ home = getenv("HOME");
+ len = strlen(PACKAGE_DATA_DIR "/../") + strlen(__ecore_config_app_name) +
+ strlen("/themes/") + 1;
+ if (home)
+ len += strlen(home) + strlen("/.e/apps/") +
+ strlen(__ecore_config_app_name) +
+ strlen("/themes/|"); /* no \0, as that is above */
+
+ if (!(path = malloc(len)))
+ return NULL;
+
+ *path = '\0';
+ if (home)
+ {
+ strcat(path, home);
+ strcat(path, "/.e/apps/");
+ strcat(path, __ecore_config_app_name);
+ strcat(path, "/themes/|");
+ }
+ strcat(path, PACKAGE_DATA_DIR "/../");
+ strcat(path, __ecore_config_app_name);
+ strcat(path, "/themes/");
+
+ return path;
+}
+
+/**
+ * Retrieves the search path used to find themes.
+ *
+ * The search path is stored in the property "/e/themes/search_path". If
+ * the property has not been set, the default path used is
+ * "/usr/local/share/<app_name>/themes|~/.e/apps/<app_name>/themes".
+ * See @ref ecore_config_theme_default_path_get for more information about
+ * the default path.
+ *
+ * @return The search path. @c NULL is returned if there is no memory left.
+ */
+char *
+ecore_config_theme_search_path_get(void)
+{
+ char *search_path;
+ search_path = ecore_config_string_get("/e/themes/search_path");
+
+ /* this should no longer be the case, as it is defaulted in init */
+ if (!search_path)
+ {
+ search_path = ecore_config_theme_default_path_get();
+ if (search_path)
+ {
+ ecore_config_string_default("/e/themes/search_path", search_path);
+ free(search_path);
+ }
+ }
+ return search_path;
+}
+
+/**
+ * Adds the given path to the search path used to find themes.
+ *
+ * If the search path is successfully, the new search path will be saved
+ * into the property "/e/themes/search_path". Therefore, this function
+ * should be called @b after @ref ecore_config_load to allow a user to
+ * override the default search path.
+ *
+ * @param path The given
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL
+ * will be returned if @p path already exists in the search path.
+ * @c ECORE_CONFIG_ERR_FAIL is returned if @p path is @c NULL.
+ */
+int
+ecore_config_theme_search_path_append(const char *path)
+{
+ char *search_path, *loc, *new_search_path;
+ int len, search_len;
+ Ecore_Config_Prop *prop;
+
+ if (!path)
+ return ECORE_CONFIG_ERR_NODATA;
+ search_path = ecore_config_theme_search_path_get();
+
+ loc = strstr(search_path, path);
+ len = strlen(path);
+ search_len = strlen(search_path);
+
+ if (loc == NULL || (loc != search_path && *(loc - 1) != '|') ||
+ (loc != (search_path + search_len - len) && *(loc + len - 1) != '|'))
+ {
+ new_search_path = malloc(search_len + len + 2); /* 2 = \0 + | */
+ strcpy(new_search_path, search_path);
+ strncat(new_search_path, "|", 1);
+ strncat(new_search_path, path, len);
+
+ ecore_config_string_set("/e/themes/search_path", new_search_path);
+ prop = ecore_config_get("/e/themes/search_path");
+ if (prop)
+ prop->flags &= ~ECORE_CONFIG_FLAG_MODIFIED;
+
+ free(new_search_path);
+
+ return ECORE_CONFIG_ERR_SUCC;
+ }
+ return ECORE_CONFIG_ERR_FAIL;
+}
+
+/**
+ * Retrieve a theme file's full path.
+ *
+ * The search path for theme files is given by @ref
+ * ecore_config_theme_search_path_get .
+ *
+ * @param name The name of the theme.
+ * @return A full path to the theme on success. @c NULL will be returned
+ * if @p name is @c NULL or no theme matching the given name could
+ * be found.
+ */
+char *
+ecore_config_theme_with_path_from_name_get(char *name)
+{
+ char *search_path, *search_path_tmp, *ptr, *end, *file;
+ struct stat st;
+
+ if (!name)
+ return NULL; /* no theme specified (nor a default) */
+
+ search_path = ecore_config_theme_search_path_get();
+ ptr = search_path;
+ end = search_path + strlen(search_path);
+ search_path_tmp = search_path;
+ while (ptr && ptr < end)
+ {
+ while (*ptr != '|' && ptr < end)
+ ptr++;
+ if (ptr < end)
+ *ptr = '\0';
+
+ file = malloc(strlen(search_path_tmp) + strlen(name) + 6);
+ /* 6 = / + .edj + \0 */
+
+ snprintf(file, strlen(search_path_tmp) + strlen(name) + 6,
+ "%s/%s.edj", search_path_tmp, name);
+
+ if (stat(file, &st) == 0)
+ {
+ free(search_path);
+ return file;
+ }
+ free(file);
+ ptr++;
+ search_path_tmp = ptr;
+ }
+
+ free(search_path);
+
+ return NULL; /* we could not find the theme with that name in search path */
+}
+
+/**
+ * Retrieves the full path to the theme file of the theme stored in the
+ * given property.
+ *
+ * The search path for themes is given by @ref
+ * ecore_config_theme_search_path_get .
+ *
+ * @param key The given property.
+ * @return A full path to the theme on success, or @c NULL on failure.
+ * This function will fail if no key is specified or not theme
+ * matching that given by the property @p key could be found.
+ */
+char *
+ecore_config_theme_with_path_get(const char *key)
+{
+ return
+ ecore_config_theme_with_path_from_name_get(ecore_config_theme_get(key));
+}
+
+static const char *_ecore_config_short_types[] =
+ { " ", "<int> ", "<flt> ", "<str> ", "<rgb> ", "<str> ", "<bool>" };
+
+/**
+ * Prints the property list of the local configuration bundle to output.
+ */
+void
+ecore_config_args_display(void)
+{
+ Ecore_Config_Prop *props;
+ _Ecore_Config_Arg_Callback *callbacks;
+
+ if (__ecore_config_app_description)
+ ERR("%s\n\n", __ecore_config_app_description);
+ ERR("Supported Options:");
+ ERR(" -h, --help\t Print this text");
+ if (!__ecore_config_bundle_local)
+ return;
+ props = __ecore_config_bundle_local->data;
+ while (props)
+ {
+ /* if it is a system prop, or cannot be set on command line hide it */
+ if (props->flags & ECORE_CONFIG_FLAG_SYSTEM || (!props->short_opt && !props->long_opt))
+ {
+ props = props->next;
+ continue;
+ }
+ INF(" %c%c%c --%s\t%s %s", props->short_opt ? '-' : ' ',
+ props->short_opt ? props->short_opt : ' ',
+ props->short_opt ? ',' : ' ',
+ props->long_opt ? props->long_opt : props->key,
+ _ecore_config_short_types[props->type],
+ props->description ? props->description :
+ "(no description available)");
+
+ props = props->next;
+ }
+ callbacks = _ecore_config_arg_callbacks;
+ while (callbacks)
+ {
+ INF(" %c%c%c --%s\t%s %s", callbacks->short_opt ? '-' : ' ',
+ callbacks->short_opt ? callbacks->short_opt : ' ',
+ callbacks->short_opt ? ',' : ' ',
+ callbacks->long_opt ? callbacks->long_opt : "",
+ _ecore_config_short_types[callbacks->type],
+ callbacks->description ? callbacks->description :
+ "(no description available)");
+
+ callbacks = callbacks->next;
+ }
+}
+
+static int
+ecore_config_parse_set(Ecore_Config_Prop * prop, char *arg, char *opt,
+ char opt2)
+{
+ if (!arg)
+ {
+ if (opt)
+ ERR("Missing expected argument for option --%s", opt);
+ else
+ ERR("Missing expected argument for option -%c", opt2);
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ else
+ {
+ ecore_config_set(prop->key, arg);
+ prop->flags |= ECORE_CONFIG_FLAG_CMDLN;
+ }
+ return ECORE_CONFIG_PARSE_CONTINUE;
+}
+
+static void
+ecore_config_args_callback_add(char short_opt, char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data, Ecore_Config_Type type) {
+ _Ecore_Config_Arg_Callback *new_cb;
+
+ new_cb = malloc(sizeof(_Ecore_Config_Arg_Callback));
+ new_cb->short_opt = short_opt;
+ if (long_opt)
+ new_cb->long_opt = strdup(long_opt);
+ if (desc)
+ new_cb->description = strdup(desc);
+ new_cb->data = data;
+ new_cb->func = func;
+ new_cb->type = type;
+
+ new_cb->next = _ecore_config_arg_callbacks;
+ _ecore_config_arg_callbacks = new_cb;
+}
+
+void
+ecore_config_args_callback_str_add(char short_opt, char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data) {
+ ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, ECORE_CONFIG_STR);
+}
+
+void
+ecore_config_args_callback_noarg_add(char short_opt, char *long_opt, char *desc,
+ void (*func)(char *val, void *data),
+ void *data) {
+ ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, ECORE_CONFIG_NIL);
+}
+
+/**
+ * Parse the arguments set by @ref ecore_app_args_set and set properties
+ * accordingly.
+ *
+ * @return @c ECORE_CONFIG_PARSE_CONTINUE if successful.
+ * @c ECORE_CONFIG_PARSE_EXIT is returned if an unrecognised option
+ * is found. @c ECORE_CONFIG_PARSE_HELP is returned if help was
+ * displayed.
+ */
+int
+ecore_config_args_parse(void)
+{
+ int argc;
+ char **argv;
+ int nextarg, next_short_opt, found, ret;
+ char *arg;
+ char *long_opt, short_opt;
+ Ecore_Config_Prop *prop;
+ _Ecore_Config_Arg_Callback *callback;
+
+ ecore_app_args_get(&argc, &argv);
+ nextarg = 1;
+ while (nextarg < argc)
+ {
+ arg = argv[nextarg];
+
+ if (*arg != '-')
+ {
+ ERR("Unexpected attribute \"%s\"", arg);
+ nextarg++;
+ continue;
+ }
+
+ next_short_opt = 1;
+ short_opt = *(arg + next_short_opt);
+
+ if (short_opt == '-')
+ {
+ long_opt = arg + 2;
+
+ if (!strcmp(long_opt, "help"))
+ {
+ ecore_config_args_display();
+ return ECORE_CONFIG_PARSE_HELP;
+ }
+
+ found = 0;
+ prop = __ecore_config_bundle_local->data;
+ while (prop)
+ {
+ if ((prop->long_opt && !strcmp(long_opt, prop->long_opt))
+ || !strcmp(long_opt, prop->key))
+ {
+ found = 1;
+ if ((ret =
+ ecore_config_parse_set(prop, argv[++nextarg],
+ long_opt,
+ '\0')) !=
+ ECORE_CONFIG_PARSE_CONTINUE)
+ return ret;
+ break;
+ }
+ prop = prop->next;
+ }
+ if (!found)
+ {
+ callback = _ecore_config_arg_callbacks;
+ while (callback)
+ {
+ if ((callback->long_opt &&
+ !strcmp(long_opt, callback->long_opt)))
+ {
+ found = 1;
+ if (callback->type == ECORE_CONFIG_NIL)
+ {
+ callback->func(NULL, callback->data);
+ }
+ else
+ {
+ if (!argv[++nextarg])
+ {
+ ERR("Missing expected argument for option --%s", long_opt);
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ callback->func(argv[nextarg], callback->data);
+ }
+ break;
+ }
+ callback = callback->next;
+ }
+ }
+ if (!found)
+ {
+ ERR("Unrecognised option \"%s\"", long_opt);
+ ERR("Try using -h or --help for more information.\n");
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ }
+ else
+ {
+ while (short_opt)
+ {
+ if (short_opt == 'h')
+ {
+ ecore_config_args_display();
+ return ECORE_CONFIG_PARSE_HELP;
+ }
+ else
+ {
+ found = 0;
+ prop = __ecore_config_bundle_local->data;
+ while (prop)
+ {
+ if (short_opt == prop->short_opt)
+ {
+ found = 1;
+ if ((ret =
+ ecore_config_parse_set(prop,
+ argv[++nextarg],
+ NULL,
+ short_opt)) !=
+ ECORE_CONFIG_PARSE_CONTINUE)
+ return ret;
+ break;
+ }
+ prop = prop->next;
+ }
+
+ if (!found)
+ {
+ callback = _ecore_config_arg_callbacks;
+ while (callback)
+ {
+ if (short_opt == callback->short_opt)
+ {
+ found = 1;
+ if (callback->type == ECORE_CONFIG_NIL)
+ {
+ callback->func(NULL, callback->data);
+ }
+ else
+ {
+ if (!argv[++nextarg])
+ {
+ ERR("Missing expected argument for option -%c", short_opt);
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ callback->func(argv[nextarg], callback->data);
+ }
+ break;
+ }
+ callback = callback->next;
+ }
+ }
+ if (!found)
+ {
+ ERR("Unrecognised option '%c'", short_opt);
+ ERR("Try using -h or --help for more information.\n");
+ return ECORE_CONFIG_PARSE_EXIT;
+ }
+ }
+ short_opt = *(arg + ++next_short_opt);
+ }
+ }
+ nextarg++;
+ }
+
+ return ECORE_CONFIG_PARSE_CONTINUE;
+}
+
+/**
+ * Sets the description string used by @ref ecore_config_args_display .
+ * @param description Description of application.
+ */
+void
+ecore_config_app_describe(char *description)
+{
+ if (__ecore_config_app_description)
+ free(__ecore_config_app_description);
+ __ecore_config_app_description = strdup(description);
+}
--- /dev/null
+#include <Ecore_Ipc.h>
+#include "Ecore_Config.h"
+
+typedef enum
+{
+ IPC_NONE,
+ IPC_PROP_LIST,
+ IPC_PROP_DESC,
+ IPC_PROP_GET,
+ IPC_PROP_SET, /* end of the codes shared by evidence and econf */
+
+ IPC_GLOBAL_PROP_LIST,
+
+ IPC_BUNDLE_LIST,
+ IPC_BUNDLE_NEW,
+ IPC_BUNDLE_LABEL_GET,
+ IPC_BUNDLE_LABEL_SET,
+ IPC_BUNDLE_LABEL_FIND,
+
+ IPC_LAST
+} Ecore_Config_Ipc_Call;
+
+Ecore_Config_Server *_ecore_config_ipc_init(const char *pipe_name);
+int _ecore_config_ipc_exit(void);
+
+Ecore_Config_Server *_ecore_config_server_convert(void *srv);
+
+char *_ecore_config_ipc_prop_list(Ecore_Config_Server * srv,
+ const long serial);
+char *_ecore_config_ipc_prop_desc(Ecore_Config_Server * srv,
+ const long serial,
+ const char *key);
+char *_ecore_config_ipc_prop_get(Ecore_Config_Server * srv,
+ const long serial,
+ const char *key);
+int _ecore_config_ipc_prop_set(Ecore_Config_Server * srv,
+ const long serial,
+ const char *key,
+ const char *val);
+
+char *_ecore_config_ipc_bundle_list(Ecore_Config_Server * srv);
+int _ecore_config_ipc_bundle_new(Ecore_Config_Server * srv,
+ const char *);
+char *_ecore_config_ipc_bundle_label_get(Ecore_Config_Server *
+ srv, const long);
+int _ecore_config_ipc_bundle_label_set(Ecore_Config_Server *
+ srv, const long,
+ const char *);
+long _ecore_config_ipc_bundle_label_find(Ecore_Config_Server *
+ srv, const char *);
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* by Azundris, with thanks to Corey Donohoe <atmos@atmos.org> */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <Ecore.h>
+#include "ecore_private.h"
+#include <Ecore_Ipc.h>
+
+#include "ecore_config_ipc.h"
+#include "ecore_config_util.h"
+#include "ecore_config_private.h"
+
+#include "Ecore_Config.h"
+
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_ecore_string_get(char **m, char **r)
+{
+ char *q;
+ int l = 0;
+
+ if (!m || !*m)
+ return ECORE_CONFIG_ERR_NODATA;
+ if (!r)
+ return ECORE_CONFIG_ERR_FAIL;
+ q = *m;
+ if (*q != 's')
+ return ECORE_CONFIG_ERR_TYPEMISMATCH;
+ q++;
+ l = (*(q++)) << 8;
+ l += *(q++);
+ *r = q;
+ q += l;
+ *m = q;
+ WRN("IPC/eCore: got string-%d \"%s\"", l, *r);
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+static char *
+_ecore_config_ipc_global_prop_list(Ecore_Config_Server * srv __UNUSED__, long serial __UNUSED__)
+{
+ Ecore_Config_DB_File *db;
+ char **keys;
+ int key_count, x;
+ estring *s;
+ int f;
+ char buf[PATH_MAX], *p;
+ // char *data; UNUSED
+ Ecore_Config_Type type;
+
+ db = NULL;
+ s = estring_new(8192);
+ f = 0;
+ if ((p = getenv("HOME")))
+ {
+ snprintf(buf, sizeof(buf), "%s/.e/config.eet", p);
+ if (!(db = _ecore_config_db_open_read(buf)))
+ {
+ strcpy(buf, PACKAGE_DATA_DIR"/system.eet");
+ if (!(db = _ecore_config_db_open_read(buf)))
+ return NULL;
+ }
+ }
+ if (!db) return NULL;
+ key_count = 0;
+ keys = _ecore_config_db_keys_get(db, &key_count);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ type = _ecore_config_db_key_type_get(db, keys[x]);
+ switch (type)
+ {
+ case ECORE_CONFIG_INT:
+ estring_appendf(s, "%s%s: integer", f ? "\n" : "", keys[x]);
+ break;
+ case ECORE_CONFIG_BLN:
+ estring_appendf(s, "%s%s: boolean", f ? "\n" : "", keys[x]);
+ break;
+ case ECORE_CONFIG_FLT:
+ estring_appendf(s, "%s%s: float", f ? "\n" : "", keys[x]);
+ break;
+ case ECORE_CONFIG_STR:
+ estring_appendf(s, "%s%s: string", f ? "\n" : "", keys[x]);
+ break;
+ case ECORE_CONFIG_RGB:
+ estring_appendf(s, "%s%s: colour", f ? "\n" : "", keys[x]);
+ break;
+ case ECORE_CONFIG_THM:
+ estring_appendf(s, "%s%s: theme", f ? "\n" : "", keys[x]);
+ break;
+ case ECORE_CONFIG_SCT:
+ estring_appendf(s, "%s%s: structure", f ? "\n" : "", keys[x]);
+ break;
+ default:
+ estring_appendf(s, "%s%s: unknown", f ? "\n" : "", keys[x]);
+ continue;
+ }
+ f = 1;
+ }
+ }
+ _ecore_config_db_close(db);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ free(keys[x]);
+ }
+ free(keys);
+ }
+
+ return estring_disown(s);
+}
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_ecore_send(Ecore_Ipc_Event_Client_Data * e, int code,
+ char *reply)
+{
+ static int our_ref = 0;
+ int len = reply ? strlen(reply) + 1 : 0;
+
+ our_ref++;
+ WRN("IPC/eCore: replying [0,0] %d IRT %d => %d {\"%s\":%d}", our_ref,
+ e->ref, code, reply ? reply : "", len);
+ return ecore_ipc_client_send(e->client, 0, 0, our_ref, e->ref, code, reply,
+ len);
+}
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_ecore_handle_request(Ecore_Ipc_Server * server,
+ Ecore_Ipc_Event_Client_Data * e)
+{
+ Ecore_Config_Server *srv;
+ long serial;
+ int ret;
+ char *r, *k, *v, *m;
+
+ srv = _ecore_config_server_convert(server);
+ serial = e->minor;
+ r = NULL;
+ m = (char *)e->data;
+ INF("IPC/eCore: client sent: [%d,%d] #%d (%d) @ %p", e->major, e->minor,
+ e->ref, e->size, server);
+
+ switch (e->major)
+ {
+ case IPC_PROP_LIST:
+ if (srv == __ecore_config_server_global)
+ r = _ecore_config_ipc_global_prop_list(srv, serial);
+ else
+ r = _ecore_config_ipc_prop_list(srv, serial);
+ break;
+ case IPC_PROP_DESC:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ r = _ecore_config_ipc_prop_desc(srv, serial, k);
+ break;
+ case IPC_PROP_GET:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ r = _ecore_config_ipc_prop_get(srv, serial, k);
+ break;
+ case IPC_PROP_SET:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ {
+ if (_ecore_config_ipc_ecore_string_get(&m, &v) ==
+ ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ _ecore_config_ipc_prop_set
+ (srv, serial, k, v), NULL);
+ }
+ break;
+
+ case IPC_BUNDLE_LIST:
+ r = _ecore_config_ipc_bundle_list(srv);
+ break;
+ case IPC_BUNDLE_NEW:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ k ?
+ _ecore_config_ipc_bundle_new(srv,
+ k) :
+ ECORE_CONFIG_ERR_FAIL, NULL);
+ break;
+ case IPC_BUNDLE_LABEL_SET:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ k ?
+ _ecore_config_ipc_bundle_label_set
+ (srv, serial,
+ k) : ECORE_CONFIG_ERR_FAIL,
+ NULL);
+ break;
+ case IPC_BUNDLE_LABEL_FIND:
+ if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
+ return _ecore_config_ipc_ecore_send(e,
+ _ecore_config_ipc_bundle_label_find
+ (srv, k), NULL);
+ break;
+ case IPC_BUNDLE_LABEL_GET:
+ r = _ecore_config_ipc_bundle_label_get(srv, serial);
+ break;
+ }
+
+ ret =
+ _ecore_config_ipc_ecore_send(e,
+ r ? ECORE_CONFIG_ERR_SUCC :
+ ECORE_CONFIG_ERR_FAIL, r);
+ if (r)
+ {
+ free(r);
+ return ret;
+ }
+ return ECORE_CONFIG_ERR_NOTFOUND;
+}
+
+/*****************************************************************************/
+
+static int
+_ecore_config_ipc_client_add(void *data, int type __UNUSED__, void *event)
+{
+ Ecore_Ipc_Server **server;
+ Ecore_Ipc_Event_Client_Data *e;
+
+ server = (Ecore_Ipc_Server **) data;
+ e = (Ecore_Ipc_Event_Client_Data *) event;
+
+ if (*server != ecore_ipc_client_server_get(e->client))
+ return 1;
+
+ INF("IPC/eCore: Client connected. @ %p", server);
+ return 1;
+}
+
+static int
+_ecore_config_ipc_client_del(void *data, int type __UNUSED__, void *event)
+{
+ Ecore_Ipc_Server **server;
+ Ecore_Ipc_Event_Client_Data *e;
+
+ server = (Ecore_Ipc_Server **) data;
+ e = (Ecore_Ipc_Event_Client_Data *) event;
+
+ if (*server != ecore_ipc_client_server_get(e->client))
+ return 1;
+
+ INF("IPC/eCore: Client disconnected. @ %p", server);
+ return 1;
+}
+
+static int
+_ecore_config_ipc_client_sent(void *data, int type __UNUSED__, void *event)
+{
+ Ecore_Ipc_Server **server;
+ Ecore_Ipc_Event_Client_Data *e;
+
+ server = (Ecore_Ipc_Server **) data;
+ e = (Ecore_Ipc_Event_Client_Data *) event;
+
+ if (*server != ecore_ipc_client_server_get(e->client))
+ return 1;
+
+ _ecore_config_ipc_ecore_handle_request(*server, e);
+ return 1;
+}
+
+/*****************************************************************************/
+
+int
+_ecore_config_ipc_ecore_init(const char *pipe_name, void **data)
+{
+ Ecore_Ipc_Server **server;
+ struct stat st;
+ char *p;
+ int port;
+ char socket[PATH_MAX];
+
+ server = (Ecore_Ipc_Server **) data;
+ port = 0;
+ if (!server)
+ return ECORE_CONFIG_ERR_FAIL;
+
+/* if(*server)
+ return ECORE_CONFIG_ERR_IGNORED; */
+
+ ecore_init();
+ if (ecore_ipc_init() < 1)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if ((p = getenv("HOME")))
+ { /* debug-only ### FIXME */
+ int stale;
+
+ stale = 1;
+ while (stale)
+ {
+ snprintf(socket, PATH_MAX, "%s/.ecore/%s/%d", p, pipe_name, port);
+
+ if (!stat(socket, &st))
+ {
+ INF("IPC/eCore: pipe \"%s\" already exists!?", socket);
+/* if(unlink(buf))
+ E(0,"IPC/eCore: could not remove pipe \"%s\": %d\n",buf,errno); }}*/
+ port++;
+ }
+ else
+ {
+ stale = 0;
+ }
+ }
+ }
+ *server = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, pipe_name, port, NULL);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
+ _ecore_config_ipc_client_add, server);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
+ _ecore_config_ipc_client_del, server);
+ ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
+ _ecore_config_ipc_client_sent, server);
+
+ if (server)
+ {
+ INF("IPC/eCore: Server is listening on %s.", pipe_name);
+ }
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+int
+_ecore_config_ipc_ecore_exit(void **data)
+{
+ int ret;
+ Ecore_Ipc_Server **server;
+
+ ret = ECORE_CONFIG_ERR_SUCC;
+ server = (Ecore_Ipc_Server **) data;
+
+ if (!server)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if (*server)
+ {
+ ecore_ipc_server_del(*server);
+ *server = NULL;
+ }
+
+ ecore_ipc_shutdown();
+ ecore_shutdown();
+
+ return ret;
+}
+
+/*****************************************************************************/
+
+int
+_ecore_config_ipc_ecore_poll(void **data)
+{
+ Ecore_Ipc_Server **server;
+
+ server = (Ecore_Ipc_Server **) data;
+
+ if (!server)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ ecore_main_loop_iterate();
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+/*****************************************************************************/
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* ############## bad */
+#define HAVE_EVAS2
+
+#include <signal.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <glob.h>
+#include <sys/param.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h> /* malloc(), free() */
+
+#include "Ecore.h"
+#include "Ecore_Config.h"
+#include "ecore_config_util.h"
+#include "ecore_config_ipc.h"
+
+#include "ecore_config_private.h"
+
+static Ecore_Config_Server *__ecore_config_servers;
+Ecore_Timer *ipc_timer = NULL;
+
+Ecore_Config_Server *
+_ecore_config_server_convert(void *srv)
+{
+ Ecore_Config_Server *srv_tmp;
+
+ srv_tmp = __ecore_config_servers;
+ while (srv_tmp)
+ {
+ if (srv_tmp->server == srv)
+ return srv_tmp;
+ srv_tmp = srv_tmp->next;
+ }
+
+ return __ecore_config_server_global;
+}
+
+/*****************************************************************************/
+/* INTERFACE FOR IPC MODULES */
+/*****************************/
+
+char *
+_ecore_config_ipc_prop_list(Ecore_Config_Server * srv, const long serial)
+{
+ Ecore_Config_Bundle *theme;
+ Ecore_Config_Prop *e;
+ estring *s;
+ int f;
+
+ theme = ecore_config_bundle_by_serial_get(srv, serial);
+ e = theme ? theme->data : NULL;
+ s = estring_new(8192);
+ f = 0;
+ while (e)
+ {
+ /* ignore system properties in listings, unless they have been overridden */
+ if (e->flags & ECORE_CONFIG_FLAG_SYSTEM && !(e->flags & ECORE_CONFIG_FLAG_MODIFIED))
+ {
+ e = e->next;
+ continue;
+ }
+ estring_appendf(s, "%s%s: %s", f ? "\n" : "", e->key,
+ ecore_config_type_get(e));
+ if (e->flags & ECORE_CONFIG_FLAG_BOUNDS)
+ {
+ if (e->type == ECORE_CONFIG_FLT)
+ estring_appendf(s, ", range %le..%le",
+ (float)e->lo / ECORE_CONFIG_FLOAT_PRECISION,
+ (float)e->hi / ECORE_CONFIG_FLOAT_PRECISION);
+ else
+ estring_appendf(s, ", range %d..%d", e->lo, e->hi);
+ }
+ if (e->type == ECORE_CONFIG_THM)
+ estring_appendf(s, ", group %s", e->data ? e->data : "Main");
+ f = 1;
+ e = e->next;
+ }
+
+ return estring_disown(s);
+}
+
+char *
+_ecore_config_ipc_prop_desc(Ecore_Config_Server * srv, const long serial,
+ const char *key)
+{
+#ifdef HAVE_EVAS2
+ Ecore_Config_Prop *e;
+
+ e = ecore_config_get(key);
+ if (e)
+ {
+ estring *s = estring_new(512);
+
+ estring_appendf(s, "%s: %s", e->key, ecore_config_type_get(e));
+ if (e->flags & ECORE_CONFIG_FLAG_BOUNDS)
+ estring_appendf(s, ", range %d..%d", e->lo, e->hi);
+ return estring_disown(s);
+ }
+#endif
+ return strdup("<undefined>");
+}
+
+char *
+_ecore_config_ipc_prop_get(Ecore_Config_Server * srv, const long serial,
+ const char *key)
+{
+#ifdef HAVE_EVAS2
+ char *ret;
+
+ if ((ret = ecore_config_as_string_get(key)))
+ return ret;
+#endif
+ return strdup("<undefined>");
+}
+
+int
+_ecore_config_ipc_prop_set(Ecore_Config_Server * srv, const long serial,
+ const char *key, const char *val)
+{
+#ifdef HAVE_EVAS2
+ int ret;
+ Ecore_Config_Bundle *theme;
+
+ theme = ecore_config_bundle_by_serial_get(srv, serial);
+ ret = ecore_config_set(key, (char *)val);
+ ERR("ipc.prop.set(%s->%s,\"%s\") => %d\n", theme ? theme->identifier : "",
+ key, val, ret);
+ return ret;
+#else
+ return ECORE_CONFIG_ERR_NOTSUPP;
+#endif
+}
+
+/*****************************************************************************/
+
+char *
+_ecore_config_ipc_bundle_list(Ecore_Config_Server * srv)
+{
+ Ecore_Config_Bundle *ns;
+ estring *s;
+ int f;
+
+ ns = ecore_config_bundle_1st_get(srv);
+ s = estring_new(8192);
+ f = 0;
+ if (!ns)
+ return strdup("<no_bundles_created>");
+
+ while (ns)
+ {
+ estring_appendf(s, "%s%d: %s", f ? "\n" : "",
+ ecore_config_bundle_serial_get(ns),
+ ecore_config_bundle_label_get(ns));
+ f = 1;
+ ns = ecore_config_bundle_next_get(ns);
+ }
+
+ return estring_disown(s);
+}
+
+int
+_ecore_config_ipc_bundle_new(Ecore_Config_Server * srv, const char *label)
+{
+ if (ecore_config_bundle_new(srv, label))
+ return ECORE_CONFIG_ERR_SUCC;
+ return ECORE_CONFIG_ERR_FAIL;
+}
+
+char *
+_ecore_config_ipc_bundle_label_get(Ecore_Config_Server * srv, const long serial)
+{
+ Ecore_Config_Bundle *ns;
+ char *label;
+
+ ns = ecore_config_bundle_by_serial_get(srv, serial);
+ label = ecore_config_bundle_label_get(ns);
+ return strdup(label ? label : "<no such bundle>");
+}
+
+int
+_ecore_config_ipc_bundle_label_set(Ecore_Config_Server * srv, const long serial,
+ const char *label)
+{
+ Ecore_Config_Bundle *ns;
+
+ ns = ecore_config_bundle_by_serial_get(srv, serial);
+ if (!(ns->identifier = malloc(sizeof(label))))
+ return ECORE_CONFIG_ERR_OOM;
+ memcpy(ns->identifier, label, sizeof(label));
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+long
+_ecore_config_ipc_bundle_label_find(Ecore_Config_Server * srv,
+ const char *label)
+{
+ Ecore_Config_Bundle *ns;
+
+ ns = ecore_config_bundle_by_label_get(srv, label);
+ return ns ? ecore_config_bundle_serial_get(ns) : -1;
+}
+
+static int
+_ecore_config_ipc_poll(void *data __UNUSED__)
+{
+ Ecore_Config_Server *s;
+
+ s = __ecore_config_servers;
+ while (s)
+ {
+ _ecore_config_ipc_ecore_poll(&s->server);
+ s = s->next;
+ }
+
+ return 1;
+}
+
+int
+_ecore_config_ipc_exit(void)
+{
+ Ecore_Config_Server *l;
+
+ if (ipc_timer)
+ ecore_timer_del(ipc_timer);
+
+ l = __ecore_config_servers;
+ while (l)
+ {
+ _ecore_config_ipc_ecore_exit(&l->server);
+ if (l->name)
+ free(l->name);
+ l = l->next;
+ }
+
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+Ecore_Config_Server *
+_ecore_config_ipc_init(const char *pipe_name)
+{
+ int ret;
+ Ecore_Config_Server *list;
+ Ecore_Config_Server *ret_srv;
+
+ list = NULL;
+ ret_srv = NULL;
+ list = NULL;
+
+ list = malloc(sizeof(Ecore_Config_Server));
+ memset(list, 0, sizeof(Ecore_Config_Server));
+ if ((ret = _ecore_config_ipc_ecore_init(pipe_name, &list->server)) != ECORE_CONFIG_ERR_SUCC)
+ {
+ ERR("_ecore_config_ipc_init: failed to register %s, code %d",
+ pipe_name, ret);
+ }
+
+ ERR("_ecore_config_ipc_init: registered \"%s\"...", pipe_name);
+
+ list->name = strdup(pipe_name);
+ list->next = __ecore_config_servers;
+
+ __ecore_config_servers = list;
+ if (!ret_srv)
+ ret_srv = list;
+
+ if (!ipc_timer)
+ ipc_timer = ecore_timer_add(100, _ecore_config_ipc_poll, NULL);
+
+ return ret_srv;
+}
+/*****************************************************************************/
--- /dev/null
+#ifndef _ECORE_CONFIG_PRIVATE_H
+# define _ECORE_CONFIG_PRIVATE_H
+#ifdef ECORE_CONFIG_DEFAULT_LOG_COLOR
+# undef ECORE_CONFIG_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_CONFIG_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+ /* eina_log related things */
+
+extern int _ecore_config_log_dom;
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_config_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_config_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_config_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_config_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_config_log_dom, __VA_ARGS__)
+
+/* debug */
+extern int DEBUG;
+
+
+typedef struct _Ecore_Config_DB_File Ecore_Config_DB_File;
+
+int _ecore_config_mod_init(const char *pipe_name, void **data);
+int _ecore_config_mod_exit(void **data);
+int _ecore_config_mod_poll(void **data);
+
+Ecore_Config_DB_File *_ecore_config_db_open_read(const char *file);
+Ecore_Config_DB_File *_ecore_config_db_open_write(const char *file);
+void _ecore_config_db_close(Ecore_Config_DB_File *db);
+char **_ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret);
+Ecore_Config_Type _ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key);
+int _ecore_config_db_read(Ecore_Config_DB_File *db, const char *key);
+void _ecore_config_db_write(Ecore_Config_DB_File *db, Ecore_Config_Prop *e);
+
+int _ecore_config_boolean_get(Ecore_Config_Prop *e);
+char *_ecore_config_string_get(Ecore_Config_Prop *e);
+long _ecore_config_int_get(Ecore_Config_Prop *e);
+int _ecore_config_argb_get(Ecore_Config_Prop *e, int *a, int *r,
+ int *g, int *b);
+char *_ecore_config_argbstr_get(Ecore_Config_Prop *e);
+long _ecore_config_argbint_get(Ecore_Config_Prop *e);
+float _ecore_config_float_get(Ecore_Config_Prop *e);
+char *_ecore_config_theme_get(Ecore_Config_Prop *e);
+
+int _ecore_config_ipc_ecore_init(const char *pipe_name, void **data);
+int _ecore_config_ipc_ecore_exit(void **data);
+int _ecore_config_ipc_ecore_poll(void **data);
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "Ecore_Config.h"
+#include "ecore_config_private.h"
+
+/**
+ * Loads the default configuration.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the file cannot be loaded.
+ * @ingroup Ecore_Config_File_Group
+ */
+EAPI int
+ecore_config_load(void)
+{
+ char file[PATH_MAX];
+
+ if (!__ecore_config_app_name)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"),
+ __ecore_config_app_name);
+ return ecore_config_file_load(file);
+}
+
+/**
+ * Saves the current configuration to the default file.
+ * @return @c ECORE_CONFIG_ERR_SUCC is returned on success.
+ * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be
+ * saved.
+ * @ingroup Ecore_Config_File_Group
+ */
+EAPI int
+ecore_config_save(void)
+{
+ char file[PATH_MAX];
+
+ if (!__ecore_config_app_name)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"),
+ __ecore_config_app_name);
+ return ecore_config_file_save(file);
+}
+
+/**
+ * Load the given configuration file to the local configuration.
+ * @param file Name of the file to load.
+ * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA
+ * is returned if the file cannot be loaded.
+ * @ingroup Ecore_Config_File_Group
+ */
+EAPI int
+ecore_config_file_load(const char *file)
+{
+ Ecore_Config_DB_File *db;
+ char **keys;
+ int key_count;
+ int x;
+ // double ftmp; UNUSED
+ // int pt; UNUSED
+ // int itmp; UNUSED
+ // Ecore_Config_Type type; UNUSED
+ char *data;
+
+ db = NULL;
+ data = NULL;
+
+ db = _ecore_config_db_open_read(file);
+ if (!db)
+ {
+ ERR("Cannot open database from file %s!", file);
+ return ECORE_CONFIG_ERR_NODATA;
+ }
+ key_count = 0;
+ keys = _ecore_config_db_keys_get(db, &key_count);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ _ecore_config_db_read(db, keys[x]);
+ }
+ }
+ _ecore_config_db_close(db);
+ if (keys)
+ {
+ for (x = 0; x < key_count; x++)
+ {
+ free(keys[x]);
+ }
+ free(keys);
+ }
+ return ECORE_CONFIG_ERR_SUCC;
+}
+
+static void
+_ecore_config_recurse_mkdir(const char *file)
+{
+ char *file_ptr;
+ char *file_tmp;
+ struct stat status;
+
+ file_tmp = strdup(file);
+ file_ptr = file_tmp + strlen(file_tmp);
+ while (*file_ptr != '/' && file_ptr > file_tmp)
+ file_ptr--;
+ *file_ptr = '\0';
+
+ if ((file_tmp[0] != 0) && stat(file_tmp, &status))
+ {
+ _ecore_config_recurse_mkdir(file_tmp);
+ mkdir(file_tmp, S_IRUSR | S_IWUSR | S_IXUSR);
+ }
+ free(file_tmp);
+}
+
+/**
+ * Saves the local configuration to the given file.
+ * @param file Name of the file to save to.
+ * @return @c ECORE_CONFIG_ERR_SUCC is returned on success.
+ * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be
+ * saved.
+ * @ingroup Ecore_Config_File_Group
+ */
+EAPI int
+ecore_config_file_save(const char *file)
+{
+ Ecore_Config_Prop *next;
+ Ecore_Config_DB_File *db;
+ struct stat status;
+
+ next = __ecore_config_bundle_local->data;
+ db = NULL;
+
+ /* if file does not exist check to see if the dirs exist, creating if not */
+ if (stat(file, &status))
+ _ecore_config_recurse_mkdir(file);
+
+ db = _ecore_config_db_open_write(file);
+ if (!db)
+ {
+ ERR("Cannot open database from file %s!", file);
+ return ECORE_CONFIG_ERR_FAIL;
+ }
+
+ while (next)
+ {
+ /* let the config_db deal with this
+ * handyande: hmm, not sure that it ever does - reinstating until
+ * further discussions satisfy me!
+ */
+ if (!(next->flags & ECORE_CONFIG_FLAG_MODIFIED) || next->flags & ECORE_CONFIG_FLAG_CMDLN)
+ {
+ next = next->next;
+ continue;
+ }
+
+ _ecore_config_db_write(db, next);
+
+ next = next->next;
+ }
+
+ _ecore_config_db_close(db);
+ return ECORE_CONFIG_ERR_SUCC;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* azundris */
+
+#include <sys/types.h>
+#include <stdlib.h> /* malloc(), free() */
+#include <stdio.h>
+#include <string.h> /* str...() */
+
+#include <stdarg.h> /* varargs in sprintf/appendf */
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#include "Ecore_Config.h"
+#include "ecore_config_util.h"
+
+#include "ecore_config_private.h"
+
+#define CHUNKLEN 4096
+
+/*****************************************************************************/
+/* STRINGS */
+/***********/
+
+estring *
+estring_new(int size)
+{
+ estring *e = malloc(sizeof(estring));
+
+ if (e)
+ {
+ memset(e, 0, sizeof(estring));
+ if ((size > 0) && (e->str = malloc(size)))
+ e->alloc = size;
+ }
+ return e;
+}
+
+char *
+estring_disown(estring * e)
+{
+ if (e)
+ {
+ char *r = e->str;
+
+ free(e);
+ return r;
+ }
+ return NULL;
+}
+
+int
+estring_appendf(estring * e, const char *fmt, ...)
+{
+ int need;
+ va_list ap;
+ char *p;
+
+ if (!e)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ if (!e->str)
+ {
+ e->used = e->alloc = 0;
+ if (!(e->str = (char *)malloc(e->alloc = CHUNKLEN)))
+ return ECORE_CONFIG_ERR_OOM;
+ }
+
+ va_start(ap, fmt);
+ need = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ if (need >= (e->alloc - e->used))
+ {
+ e->alloc = e->used + need + (CHUNKLEN - (need % CHUNKLEN));
+
+ if (!(p = (char *)realloc(e->str, e->alloc)))
+ {
+ free(e->str);
+ e->alloc = e->used = 0;
+ return ECORE_CONFIG_ERR_OOM;
+ }
+ e->str = p;
+ }
+
+ va_start(ap, fmt);
+ need = vsnprintf(e->str + e->used, e->alloc - e->used, fmt, ap);
+ va_end(ap);
+
+ return e->used += need;
+}
+
+int
+esprintf(char **result, const char *fmt, ...)
+{
+ va_list ap;
+ size_t need;
+ char *n;
+
+ if (!result)
+ return ECORE_CONFIG_ERR_FAIL;
+
+ va_start(ap, fmt);
+ need = vsnprintf(NULL, 0, fmt, ap) + 1;
+ va_end(ap);
+ n = malloc(need + 1);
+
+ if (n)
+ {
+ va_start(ap, fmt);
+ need = vsnprintf(n, need, fmt, ap);
+ va_end(ap);
+
+ n[need] = 0;
+
+ if(*result)
+ free(result);
+ *result = n;
+
+ return need;
+ }
+
+ return ECORE_CONFIG_ERR_OOM;
+}
+
+/*****************************************************************************/
--- /dev/null
+#define TIMER_STOP 0
+#define TIMER_CONT 1
+
+typedef struct _estring
+{
+ char *str;
+ int alloc, used;
+} estring;
+
+estring *estring_new(int size);
+char *estring_disown(estring * e);
+int estring_appendf(estring * e, const char *fmt, ...);
+
+int esprintf(char **result, const char *fmt, ...);
--- /dev/null
+Makefile
+Makefile.in
+.libs
+.deps
+*.lo
+libecore_directfb.la
--- /dev/null
+#ifndef _ECORE_DIRECTFB_H
+#define _ECORE_DIRECTFB_H
+
+#include <directfb.h>
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EAPI extern int ECORE_DIRECTFB_EVENT_POSITION;
+EAPI extern int ECORE_DIRECTFB_EVENT_SIZE;
+EAPI extern int ECORE_DIRECTFB_EVENT_CLOSE;
+EAPI extern int ECORE_DIRECTFB_EVENT_DESTROYED;
+EAPI extern int ECORE_DIRECTFB_EVENT_GOT_FOCUS;
+EAPI extern int ECORE_DIRECTFB_EVENT_LOST_FOCUS;
+EAPI extern int ECORE_DIRECTFB_EVENT_KEY_DOWN;
+EAPI extern int ECORE_DIRECTFB_EVENT_KEY_UP;
+EAPI extern int ECORE_DIRECTFB_EVENT_BUTTON_DOWN;
+EAPI extern int ECORE_DIRECTFB_EVENT_BUTTON_UP;
+EAPI extern int ECORE_DIRECTFB_EVENT_MOTION;
+EAPI extern int ECORE_DIRECTFB_EVENT_ENTER;
+EAPI extern int ECORE_DIRECTFB_EVENT_LEAVE;
+EAPI extern int ECORE_DIRECTFB_EVENT_WHEEL;
+
+
+
+#ifndef _ECORE_DIRECTFB_WINDOW_PREDEF
+typedef struct _Ecore_DirectFB_Window Ecore_DirectFB_Window;
+#endif
+typedef struct _Ecore_DirectFB_Cursor Ecore_DirectFB_Cursor;
+
+typedef struct _Ecore_DirectFB_Event_Key_Down Ecore_DirectFB_Event_Key_Down;
+typedef struct _Ecore_DirectFB_Event_Key_Up Ecore_DirectFB_Event_Key_Up;
+typedef struct _Ecore_DirectFB_Event_Button_Down Ecore_DirectFB_Event_Button_Down;
+typedef struct _Ecore_DirectFB_Event_Button_Up Ecore_DirectFB_Event_Button_Up;
+typedef struct _Ecore_DirectFB_Event_Motion Ecore_DirectFB_Event_Motion;
+typedef struct _Ecore_DirectFB_Event_Enter Ecore_DirectFB_Event_Enter;
+typedef struct _Ecore_DirectFB_Event_Leave Ecore_DirectFB_Event_Leave;
+typedef struct _Ecore_DirectFB_Event_Wheel Ecore_DirectFB_Event_Wheel;
+typedef struct _Ecore_DirectFB_Event_Got_Focus Ecore_DirectFB_Event_Got_Focus;
+typedef struct _Ecore_DirectFB_Event_Lost_Focus Ecore_DirectFB_Event_Lost_Focus;
+
+
+/* this struct is to keep windows data (id, window itself and surface) in memory as every call
+ * to DirectFB for this values (e.g window->GetSurface(window,&surface)) will increment the
+ * reference count, then we will have to release N times the data, so better we just ask for
+ them once */
+struct _Ecore_DirectFB_Window
+{
+ DFBWindowID id;
+ IDirectFBWindow *window;
+ IDirectFBSurface *surface;
+ Ecore_DirectFB_Cursor *cursor;
+
+};
+
+struct _Ecore_DirectFB_Cursor
+{
+ IDirectFBSurface *surface;
+ int hot_x;
+ int hot_y;
+
+};
+
+struct _Ecore_DirectFB_Event_Key_Down /** DirectFB Key Down event */
+{
+ char *name; /**< The name of the key that was released */
+ char *string; /**< The logical symbol of the key that was pressed */
+ char *key_compose; /**< The UTF-8 string conversion if any */
+ unsigned int time;
+ DFBWindowID win;
+};
+
+struct _Ecore_DirectFB_Event_Key_Up /** DirectFB Key Up event */
+{
+ char *name; /**< The name of the key that was released */
+ char *string; /**< The logical symbol of the key that was pressed */
+ char *key_compose; /**< The UTF-8 string conversion if any */
+ unsigned int time;
+ DFBWindowID win;
+};
+
+struct _Ecore_DirectFB_Event_Button_Down
+{
+ int button;
+ int modifiers;
+ int x, y;
+ unsigned int time;
+ int double_click : 1;
+ int triple_click : 1;
+ DFBWindowID win;
+};
+struct _Ecore_DirectFB_Event_Button_Up
+{
+ int button;
+ int modifiers;
+ int x, y;
+ unsigned int time;
+ DFBWindowID win;
+};
+struct _Ecore_DirectFB_Event_Motion
+{
+ int modifiers;
+ int x, y;
+ unsigned int time;
+ DFBWindowID win;
+};
+
+struct _Ecore_DirectFB_Event_Enter
+{
+ int modifiers;
+ int x, y;
+ unsigned int time;
+ DFBWindowID win;
+};
+
+struct _Ecore_DirectFB_Event_Leave
+{
+ int modifiers;
+ int x, y;
+ unsigned int time;
+ DFBWindowID win;
+};
+
+struct _Ecore_DirectFB_Event_Wheel
+{
+ int direction;
+ int z;
+ int modifiers;
+ unsigned int time;
+ DFBWindowID win;
+};
+
+struct _Ecore_DirectFB_Event_Got_Focus
+{
+ unsigned int time;
+ DFBWindowID win;
+};
+
+struct _Ecore_DirectFB_Event_Lost_Focus
+{
+ unsigned int time;
+ DFBWindowID win;
+};
+
+/* main functions */
+EAPI int ecore_directfb_init(const char *name);
+EAPI int ecore_directfb_shutdown(void);
+EAPI IDirectFB * ecore_directfb_interface_get(void);
+/* window operations */
+EAPI Ecore_DirectFB_Window * ecore_directfb_window_new(int x, int y, int w, int h);
+EAPI void ecore_directfb_window_free(Ecore_DirectFB_Window *window);
+EAPI void ecore_directfb_window_move(Ecore_DirectFB_Window *window, int x, int y);
+EAPI void ecore_directfb_window_resize(Ecore_DirectFB_Window *window, int w, int h);
+EAPI void ecore_directfb_window_focus(Ecore_DirectFB_Window *window);
+EAPI void ecore_directfb_window_show(Ecore_DirectFB_Window *window);
+EAPI void ecore_directfb_window_hide(Ecore_DirectFB_Window *window);
+EAPI void ecore_directfb_window_shaped_set(Ecore_DirectFB_Window *window, int set);
+EAPI void ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *window, int set);
+EAPI void ecore_directfb_window_size_get(Ecore_DirectFB_Window *window, int *w, int *h);
+EAPI void ecore_directfb_window_cursor_show(Ecore_DirectFB_Window *window, int show);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore \
+@DIRECTFB_CFLAGS@ @EINA_CFLAGS@
+
+if BUILD_ECORE_DIRECTFB
+
+lib_LTLIBRARIES = libecore_directfb.la
+include_HEADERS = \
+Ecore_DirectFB.h
+
+libecore_directfb_la_SOURCES = \
+ecore_directfb.c \
+ecore_directfb_keys.h \
+ecore_directfb_private.h
+
+libecore_directfb_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@DIRECTFB_LIBS@ \
+@EINA_LIBS@
+
+libecore_directfb_la_LDFLAGS = -version-info @version_info@ @ecore_directfb_release_info@
+
+libecore_directfb_la_DEPENDENCIES = \
+$(top_builddir)/src/lib/ecore/libecore.la
+
+endif
+
+EXTRA_DIST = \
+Ecore_DirectFB.h \
+ecore_directfb.c \
+ecore_directfb_keys.h \
+ecore_directfb_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "Ecore_DirectFB.h"
+#include "ecore_directfb_private.h"
+#include "ecore_directfb_keys.h"
+#include "Ecore.h"
+#include "ecore_private.h"
+
+/* ecore_directfb */
+/******************/
+/* About */
+/* with this you can create windows of directfb and handle events through ecore
+ * TODO:
+ * - handle all event types
+ * -
+ * */
+int _ecore_directfb_log_dom = -1;
+
+
+static int _ecore_directfb_init_count = 0;
+
+static int _window_event_fd = 0;
+static int _input_event_fd = 0;
+
+static int _ecore_directfb_fullscreen_window_id = 0;
+static int _cursor_x = 0;
+static int _cursor_y = 0;
+
+EAPI int ECORE_DIRECTFB_EVENT_POSITION = 0;
+EAPI int ECORE_DIRECTFB_EVENT_SIZE = 0;
+EAPI int ECORE_DIRECTFB_EVENT_CLOSE = 0;
+EAPI int ECORE_DIRECTFB_EVENT_DESTROYED = 0;
+EAPI int ECORE_DIRECTFB_EVENT_GOT_FOCUS = 0;
+EAPI int ECORE_DIRECTFB_EVENT_LOST_FOCUS = 0;
+EAPI int ECORE_DIRECTFB_EVENT_KEY_DOWN = 0;
+EAPI int ECORE_DIRECTFB_EVENT_KEY_UP = 0;
+EAPI int ECORE_DIRECTFB_EVENT_BUTTON_DOWN = 0;
+EAPI int ECORE_DIRECTFB_EVENT_BUTTON_UP = 0;
+EAPI int ECORE_DIRECTFB_EVENT_MOTION = 0;
+EAPI int ECORE_DIRECTFB_EVENT_ENTER = 0;
+EAPI int ECORE_DIRECTFB_EVENT_LEAVE = 0;
+EAPI int ECORE_DIRECTFB_EVENT_WHEEL = 0;
+
+
+static Ecore_Fd_Handler *_window_event_fd_handler_handle = NULL;
+static Ecore_Fd_Handler *_input_event_fd_handler_handle = NULL;
+
+/* this hash is to store all the possible key names for fast lookup */
+static Eina_Hash *_ecore_directfb_key_symbols_hash = NULL;
+
+
+static IDirectFB *_dfb = NULL; // the main interface
+static IDirectFBEventBuffer *_window_event; // the main event buffer (all windows are attached to this)
+static IDirectFBEventBuffer *_input_event; // the main event buffer (all windows are attached to this)
+static IDirectFBDisplayLayer *_layer; // the main layer
+static DFBResult _err; // usefull for DFBCHECK
+
+
+/*******************/
+/* local functions */
+/*******************/
+
+/* free ecore directfb events functions */
+/****************************************/
+
+static void
+_ecore_directfb_event_free_key_down(void *data __UNUSED__, void *ev)
+{
+ Ecore_DirectFB_Event_Key_Up *e;
+
+ e = ev;
+ if(e->name) free(e->name);
+ if (e->string) free(e->string);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_directfb_event_free_key_up(void *data __UNUSED__, void *ev)
+{
+ Ecore_DirectFB_Event_Key_Up *e;
+
+ e = ev;
+ if(e->name) free(e->name);
+ if (e->string) free(e->string);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+
+/* directfb window input events handler */
+/****************************************/
+
+static void
+_ecore_directfb_event_handle_motion(DFBEvent *evt)
+{
+
+ Ecore_DirectFB_Event_Motion *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Motion));
+
+ switch(evt->clazz)
+ {
+ case DFEC_INPUT:
+ e->modifiers = 0;
+ switch(evt->input.axis)
+ {
+ case DIAI_X:
+ e->x = _cursor_x = evt->input.axisabs;
+ e->y = _cursor_y;
+ break;
+ case DIAI_Y:
+ e->y = _cursor_y = evt->input.axisabs;
+ e->x = _cursor_x;
+ break;
+ case DIAI_Z:
+ //_ecore_directfb_event_handle_wheel(evt);
+ return;
+ default:
+ return;
+ }
+ e->win = _ecore_directfb_fullscreen_window_id;
+ e->time = 0;
+ break;
+
+ case DFEC_WINDOW:
+ e->modifiers = 0;
+ e->x = evt->window.x;
+ e->y = evt->window.y;
+ e->win = evt->window.window_id;
+ e->time = 0;
+ break;
+ default:
+ break;
+ }
+ ecore_event_add(ECORE_DIRECTFB_EVENT_MOTION, e, NULL, NULL);
+}
+static void
+_ecore_directfb_event_handle_key_down(DFBEvent *evt)
+{
+
+ Ecore_DirectFB_Event_Key_Down *e;
+ unsigned int key_symbol;
+ struct keymap *k;
+
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Down));
+
+ switch(evt->clazz)
+ {
+ case DFEC_INPUT:
+ key_symbol = evt->input.key_symbol;
+ k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
+
+ if(!k)
+ {
+ ERR("error en el numero, %0X", evt->input.key_symbol);
+ return;
+ }
+ e->name = strdup(k->name);
+ e->string = strdup(k->string);
+ e->key_compose = NULL;
+ e->win = _ecore_directfb_fullscreen_window_id;
+ e->time = 0;
+ break;
+
+ case DFEC_WINDOW:
+ key_symbol = evt->window.key_symbol;
+ k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
+
+ if(!k)
+ {
+ ERR("error en el numero, %0X", evt->window.key_symbol);
+ return;
+ }
+ e->name = strdup(k->name);
+ e->string = strdup(k->string);
+ e->key_compose = NULL;
+ e->win = evt->window.window_id;
+ e->time = 0;
+ break;
+ default:
+ break;
+ }
+
+ ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, e, _ecore_directfb_event_free_key_down, NULL);
+}
+static void
+_ecore_directfb_event_handle_key_up(DFBEvent *evt)
+{
+ Ecore_DirectFB_Event_Key_Up *e;
+ unsigned int key_symbol;
+ struct keymap *k;
+
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Key_Up));
+
+ switch(evt->clazz)
+ {
+ case DFEC_INPUT:
+ key_symbol = evt->input.key_symbol;
+ k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
+
+
+ if(!k)
+ {
+ ERR("error en el numero, %0X", evt->input.key_symbol);
+ return;
+ }
+ e->name = strdup(k->name);
+ e->string = strdup(k->string);
+ e->key_compose = NULL;
+ e->win = _ecore_directfb_fullscreen_window_id;
+ e->time = 0;
+ break;
+
+ case DFEC_WINDOW:
+ key_symbol = evt->window.key_symbol;
+ k = eina_hash_find(_ecore_directfb_key_symbols_hash, &key_symbol);
+
+ if(!k)
+ {
+ ERR("error en el numero, %0X", evt->window.key_symbol);
+ return;
+ }
+ e->name = strdup(k->name);
+ e->string = strdup(k->string);
+ e->key_compose = NULL;
+ e->win = evt->window.window_id;
+ e->time = 0;
+ break;
+ default:
+ break;
+ }
+ ecore_event_add(ECORE_DIRECTFB_EVENT_KEY_UP, e, _ecore_directfb_event_free_key_up, NULL);
+
+}
+
+static void
+_ecore_directfb_event_handle_button_down(DFBEvent *evt)
+{
+ Ecore_DirectFB_Event_Button_Down *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Down));
+
+ switch(evt->clazz)
+ {
+ case DFEC_INPUT:
+ e->button = evt->input.button + 1;
+ e->modifiers = 0;
+ DFBCHECK(_layer->GetCursorPosition(_layer,&e->x,&e->y));
+ e->x = _cursor_x;
+ e->y = _cursor_y;
+ e->win = _ecore_directfb_fullscreen_window_id;
+ e->time = 0;
+
+ break;
+
+ case DFEC_WINDOW:
+ e->button = evt->window.button + 1;
+ e->modifiers = 0;
+ e->x = evt->window.x;
+ e->y = evt->window.y;
+ e->win = evt->window.window_id;
+ e->time = 0;
+ break;
+ default:
+ break;
+ }
+
+ ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, e, NULL, NULL);
+
+}
+
+static void
+_ecore_directfb_event_handle_button_up(DFBEvent *evt)
+{
+ Ecore_DirectFB_Event_Button_Up *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Button_Up));
+
+ switch(evt->clazz)
+ {
+ case DFEC_INPUT:
+ e->button = evt->input.button + 1;
+ e->modifiers = 0;
+ e->x = _cursor_x;
+ e->y = _cursor_y;
+ e->win = _ecore_directfb_fullscreen_window_id;
+ e->time = 0;
+
+ break;
+
+ case DFEC_WINDOW:
+ e->button = evt->window.button + 1;
+ e->modifiers = 0;
+ e->x = evt->window.x;
+ e->y = evt->window.y;
+ e->win = evt->window.window_id;
+ e->time = 0;
+ break;
+ default:
+ break;
+ }
+ ecore_event_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, e, NULL, NULL);
+
+}
+
+static void
+_ecore_directfb_event_handle_enter(DFBWindowEvent *evt)
+{
+ Ecore_DirectFB_Event_Enter *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Enter));
+
+ e->modifiers = 0;
+ e->x = evt->x;
+ e->y = evt->y;
+ e->win = evt->window_id;
+ e->time = 0;
+
+ ecore_event_add(ECORE_DIRECTFB_EVENT_ENTER, e, NULL, NULL);
+
+}
+
+static void
+_ecore_directfb_event_handle_leave(DFBWindowEvent *evt)
+{
+ Ecore_DirectFB_Event_Leave *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Leave));
+
+ e->modifiers = 0;
+ e->x = evt->x;
+ e->y = evt->y;
+ e->win = evt->window_id;
+ e->time = 0;
+
+ ecore_event_add(ECORE_DIRECTFB_EVENT_LEAVE, e, NULL, NULL);
+
+}
+
+static void
+_ecore_directfb_event_handle_wheel(DFBWindowEvent *evt)
+{
+ Ecore_DirectFB_Event_Wheel *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Wheel));
+
+ // currently there's no direction (only up/down);
+ e->direction = 0;
+ e->z = evt->step;
+ e->modifiers = 0;
+ e->win = evt->window_id;
+ e->time = 0;
+
+ ecore_event_add(ECORE_DIRECTFB_EVENT_WHEEL, e, NULL, NULL);
+
+}
+
+static void
+_ecore_directfb_event_handle_got_focus(DFBWindowEvent *evt)
+{
+ Ecore_DirectFB_Event_Got_Focus *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Got_Focus));
+
+ e->win = evt->window_id;
+ e->time = 0;
+
+ ecore_event_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, e, NULL, NULL);
+
+}
+
+static void
+_ecore_directfb_event_handle_lost_focus(DFBWindowEvent *evt)
+{
+ Ecore_DirectFB_Event_Lost_Focus *e;
+ e = calloc(1, sizeof(Ecore_DirectFB_Event_Lost_Focus));
+
+ e->win = evt->window_id;
+ e->time = 0;
+
+ ecore_event_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, e, NULL, NULL);
+
+}
+
+
+/* inputs and windows fds handlers */
+/***********************************/
+/* TODO fix this to handle windows and input events (fullscreen/window mode)
+ * in fullscreen theres no window_id so get the id from a global var (only one fullscreen
+ * window at a time */
+
+
+static int
+_ecore_directfb_input_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ DFBEvent evt;
+ int v = 0;
+
+ v = read(_input_event_fd, &evt, sizeof(DFBEvent));
+ if (v < 0) return 1;
+ if (v < 1) return 1;
+
+ /* we are getting duplicate events, only parse if we are in fullscreen */
+ //if(_ecore_directfb_fullscreen_window_id == 0) break;
+ if(evt.input.type == DIET_KEYPRESS)
+ _ecore_directfb_event_handle_key_down(&evt);
+ if(evt.input.type == DIET_KEYRELEASE)
+ _ecore_directfb_event_handle_key_up(&evt);
+ if(evt.input.type == DIET_BUTTONPRESS)
+ _ecore_directfb_event_handle_button_down(&evt);
+ if(evt.input.type == DIET_BUTTONRELEASE)
+ _ecore_directfb_event_handle_button_up(&evt);
+ if(evt.input.type == DIET_AXISMOTION)
+ _ecore_directfb_event_handle_motion(&evt);
+
+ return 1;
+}
+
+static int
+_ecore_directfb_window_event_fd_handler(void *data __UNUSED__,Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ DFBEvent evt;
+ int v = 0;
+
+ v = read(_window_event_fd, &evt, sizeof(DFBEvent));
+ if (v < 0) return 1;
+ if (v < 1) return 1;
+
+ if(evt.window.type & DWET_POSITION)
+ INF("position");
+ if(evt.window.type & DWET_SIZE)
+ INF("size");
+ if(evt.window.type & DWET_CLOSE)
+ INF("close");
+ if(evt.window.type & DWET_DESTROYED)
+ INF("destroyed");
+ if(evt.window.type & DWET_GOTFOCUS)
+ _ecore_directfb_event_handle_got_focus(&evt.window);
+ if(evt.window.type & DWET_LOSTFOCUS)
+ _ecore_directfb_event_handle_lost_focus(&evt.window);
+ if(evt.window.type & DWET_KEYDOWN)
+ _ecore_directfb_event_handle_key_down(&evt);
+ if(evt.window.type & DWET_KEYUP)
+ _ecore_directfb_event_handle_key_up(&evt);
+ if(evt.window.type & DWET_BUTTONDOWN)
+ _ecore_directfb_event_handle_button_down(&evt);
+ if(evt.window.type & DWET_BUTTONUP)
+ _ecore_directfb_event_handle_button_up(&evt);
+ if(evt.window.type & DWET_MOTION)
+ _ecore_directfb_event_handle_motion(&evt);
+ if(evt.window.type & DWET_ENTER)
+ _ecore_directfb_event_handle_enter(&evt.window);
+ if(evt.window.type & DWET_LEAVE)
+ _ecore_directfb_event_handle_leave(&evt.window);
+ if(evt.window.type & DWET_WHEEL)
+ _ecore_directfb_event_handle_wheel(&evt.window);
+ return 1;
+}
+
+/* api functions */
+/*****************/
+
+
+EAPI IDirectFB *
+ecore_directfb_interface_get(void)
+{
+ return _dfb;
+}
+
+
+
+EAPI Ecore_DirectFB_Window *
+ecore_directfb_window_new(int x, int y, int w, int h)
+{
+ Ecore_DirectFB_Window *window;
+ IDirectFBWindow *dfb_window;
+ IDirectFBSurface *dfb_surface = NULL;
+ DFBWindowDescription desc;
+ DFBWindowID id;
+
+ memset(&desc, 0, sizeof(DFBWindowDescription));
+ desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
+ desc.posx = x;
+ desc.posy = y;
+ desc.width = w;
+ desc.height = h;
+ desc.caps = DWCAPS_ALPHACHANNEL;
+
+ DFBCHECK(_layer->CreateWindow(_layer, &desc, &dfb_window));
+
+ dfb_window->AttachEventBuffer(dfb_window, _window_event);
+ dfb_window->SetOptions(dfb_window,DWOP_NONE);
+ dfb_window->SetOpacity(dfb_window, 0xFF);
+
+ DFBCHECK(dfb_window->GetID(dfb_window, &id));
+ DFBCHECK(dfb_window->GetSurface(dfb_window,&dfb_surface));
+
+ window = malloc(sizeof(Ecore_DirectFB_Window));
+ window->id = id;
+ window->window = dfb_window;
+ window->surface = dfb_surface;
+ window->cursor = NULL;
+
+ return window;
+}
+
+EAPI void
+ecore_directfb_window_free(Ecore_DirectFB_Window *ecore_window)
+{
+ DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
+ DFBCHECK(ecore_window->window->Release(ecore_window->window));
+ free(ecore_window);
+}
+
+
+EAPI void
+ecore_directfb_window_move(Ecore_DirectFB_Window *ecore_window, int x, int y)
+{
+ DFBCHECK(ecore_window->window->MoveTo(ecore_window->window, x, y));
+}
+
+EAPI void
+ecore_directfb_window_resize(Ecore_DirectFB_Window *ecore_window, int w, int h)
+{
+ DFBCHECK(ecore_window->window->Resize(ecore_window->window, w, h));
+}
+
+EAPI void
+ecore_directfb_window_focus(Ecore_DirectFB_Window *ecore_window)
+{
+ DFBCHECK(ecore_window->window->RequestFocus(ecore_window->window));
+}
+
+EAPI void
+ecore_directfb_window_hide(Ecore_DirectFB_Window *ecore_window)
+{
+ DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window,0));
+
+}
+
+EAPI void
+ecore_directfb_window_show(Ecore_DirectFB_Window *ecore_window)
+{
+ DFBCHECK(ecore_window->window->SetOpacity(ecore_window->window, 0xFF));
+}
+
+EAPI void
+ecore_directfb_window_shaped_set(Ecore_DirectFB_Window *ecore_window, int set)
+{
+ DFBWindowOptions opts;
+
+ DFBCHECK(ecore_window->window->GetOptions(ecore_window->window, &opts));
+ if(set)
+ {
+ opts |= DWOP_SHAPED;
+ opts |= DWOP_ALPHACHANNEL;
+ DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
+ }
+ else
+ {
+ opts &= ~DWOP_SHAPED;
+ opts &= ~DWOP_ALPHACHANNEL;
+ DFBCHECK(ecore_window->window->SetOptions(ecore_window->window, opts));
+ }
+}
+
+EAPI void
+ecore_directfb_window_cursor_show(Ecore_DirectFB_Window *ecore_window, int show)
+{
+ if(!show)
+ {
+ /* create an empty cursor and set it */
+ IDirectFBSurface *cursor;
+ DFBSurfaceDescription desc;
+
+ memset(&desc, 0, sizeof(DFBSurfaceDescription));
+ desc.flags = (DSDESC_HEIGHT | DSDESC_WIDTH | DSDESC_PIXELFORMAT);
+ desc.width = 1;
+ desc.height = 1;
+ desc.pixelformat = DSPF_A1;
+
+ DFBCHECK(_dfb->CreateSurface(_dfb,&desc,&cursor));
+ DFBCHECK(cursor->Clear(cursor,0,0,0,0));
+ DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor, 0, 0));
+ }
+ else
+ {
+ /* we already have a cursor surface so set it*/
+ if(ecore_window->cursor)
+ {
+ DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, ecore_window->cursor->surface, ecore_window->cursor->hot_x, ecore_window->cursor->hot_y));
+ }
+ /* or just set the default directfb cursor */
+ else
+ {
+ DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
+ }
+
+ }
+}
+
+EAPI void
+ecore_directfb_window_cursor_set(Ecore_DirectFB_Window *ecore_window, Ecore_DirectFB_Cursor *cursor)
+{
+ if( (!cursor) && (ecore_window->cursor))
+ {
+ ecore_window->cursor = NULL;
+ DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, NULL, 0, 0));
+ return;
+ }
+ if(cursor)
+ {
+ ecore_window->cursor = cursor;
+ DFBCHECK(ecore_window->window->SetCursorShape(ecore_window->window, cursor->surface, cursor->hot_x, cursor->hot_y));
+
+ }
+
+}
+
+EAPI void
+ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *ecore_window, int on)
+{
+ // always release the surface (we are going to get a new one in both cases)
+ DFBCHECK(ecore_window->surface->Release(ecore_window->surface));
+ if(on)
+ {
+ DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_EXCLUSIVE));
+ DFBCHECK(_layer->GetSurface(_layer,&ecore_window->surface));
+ DFBCHECK(_dfb->CreateInputEventBuffer(_dfb, DICAPS_ALL, DFB_FALSE, &_input_event));
+ DFBCHECK(_input_event->CreateFileDescriptor(_input_event,&_input_event_fd));
+ /* the event of axismove sends one axis at a time, so we must store both */
+ DFBCHECK(_layer->GetCursorPosition(_layer,&_cursor_x,&_cursor_y));
+
+ _input_event_fd_handler_handle = ecore_main_fd_handler_add(_input_event_fd,ECORE_FD_READ,_ecore_directfb_input_event_fd_handler, NULL,NULL,NULL);
+ _ecore_directfb_fullscreen_window_id = ecore_window->id;
+ }
+ else
+ {
+ DFBCHECK(_input_event->Release(_input_event));
+ DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_SHARED));
+ DFBCHECK(ecore_window->window->GetSurface(ecore_window->window, &ecore_window->surface));
+ ecore_main_fd_handler_del(_input_event_fd_handler_handle);
+ _ecore_directfb_fullscreen_window_id = 0;
+ }
+
+}
+
+EAPI void
+ecore_directfb_window_size_get(Ecore_DirectFB_Window *ecore_window, int *w, int *h)
+{
+ DFBCHECK(ecore_window->surface->GetSize(ecore_window->surface,w,h));
+ return;
+}
+
+EAPI int
+ecore_directfb_init(const char *name __UNUSED__)
+{
+ int i = 0;
+
+ if (++_ecore_directfb_init_count != 1) return _ecore_directfb_init_count;
+ _ecore_directfb_log_dom = eina_log_domain_register("EcoreDirectFB", ECORE_DIRECTFB_DEFAULT_LOG_COLOR);
+ if(_ecore_directfb_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the Ecore directFB module.");
+ return _ecore_directfb_init_count--;
+ }
+ DFBCHECK(DirectFBInit(NULL,NULL));
+ DFBCHECK(DirectFBCreate(&_dfb));
+
+ DFBCHECK(_dfb->GetDisplayLayer(_dfb, DLID_PRIMARY, &_layer));
+ DFBCHECK(_layer->SetCooperativeLevel(_layer, DLSCL_SHARED));
+
+
+ /* window events and fd */
+ DFBCHECK(_dfb->CreateEventBuffer(_dfb, &_window_event));
+ DFBCHECK(_window_event->CreateFileDescriptor(_window_event,&_window_event_fd));
+ _window_event_fd_handler_handle = ecore_main_fd_handler_add(_window_event_fd,ECORE_FD_READ,_ecore_directfb_window_event_fd_handler, NULL,NULL,NULL);
+
+ /* register ecore directfb events */
+ ECORE_DIRECTFB_EVENT_POSITION = ecore_event_type_new();
+ ECORE_DIRECTFB_EVENT_SIZE = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_CLOSE = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_DESTROYED = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_GOT_FOCUS = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_LOST_FOCUS = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_KEY_DOWN = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_KEY_UP = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_BUTTON_DOWN = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_BUTTON_UP = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_MOTION = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_ENTER = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_LEAVE = ecore_event_type_new();;
+ ECORE_DIRECTFB_EVENT_WHEEL = ecore_event_type_new();;
+
+ /* create the hash table for the keynames */
+ _ecore_directfb_key_symbols_hash = eina_hash_int32_new(free);
+ for(i=0; i<_ecore_directfb_key_symbols_count; i++)
+ {
+ struct keymap *k;
+ k = malloc(sizeof(struct keymap));
+ k->name = _ecore_directfb_key_symbols[i].name;
+ k->string = _ecore_directfb_key_symbols[i].string;
+ eina_hash_add(_ecore_directfb_key_symbols_hash, &_ecore_directfb_key_symbols[i].id, k);
+ }
+ /* create the hash for the windows(key = windowid, val = Ecore_DirectFB_Window struct) */
+ return _ecore_directfb_init_count;
+}
+
+EAPI int
+ecore_directfb_shutdown(void)
+{
+ if (--_ecore_directfb_init_count != 0) return _ecore_directfb_init_count;
+
+ ecore_main_fd_handler_del(_window_event_fd_handler_handle);
+ eina_hash_free(_ecore_directfb_key_symbols_hash);
+
+ if(_ecore_directfb_fullscreen_window_id)
+ {
+ DFBCHECK(_input_event->Release(_input_event));
+ ecore_main_fd_handler_del(_input_event_fd_handler_handle);
+ }
+ DFBCHECK(_window_event->Release(_window_event));
+ DFBCHECK(_layer->Release(_layer));
+ DFBCHECK(_dfb->Release(_dfb));
+ eina_log_domain_unregister(_ecore_directfb_log_dom);
+ _ecore_directfb_log_dom = -1;
+ return _ecore_directfb_init_count;
+}
--- /dev/null
+typedef struct _Ecore_DirectFB_Key_Symbols Ecore_DirectFB_Key_Symbols;
+struct _Ecore_DirectFB_Key_Symbols
+{
+ char *string;
+ char *name;
+ unsigned int id;
+};
+
+static const Ecore_DirectFB_Key_Symbols _ecore_directfb_key_symbols[] = {
+ {"\010", "BackSpace",DIKS_BACKSPACE},
+ {"\011", "Tab", DIKS_TAB},
+ {"\015", "Return", DIKS_RETURN},
+ {"", "Cancel", DIKS_CANCEL},
+ {"", "Escape", DIKS_ESCAPE},
+ {" ", "space", DIKS_SPACE},
+ {"!", "exclam", DIKS_EXCLAMATION_MARK},
+ {"\"", "quotedbl", DIKS_QUOTATION},
+ {"#", "numbersign", DIKS_NUMBER_SIGN},
+ {"$", "dollar", DIKS_DOLLAR_SIGN},
+ {"%", "percent", DIKS_PERCENT_SIGN},
+ {"&", "ampersand", DIKS_AMPERSAND},
+ {"'", "apostrophe", DIKS_APOSTROPHE},
+ {"(", "parenleft", DIKS_PARENTHESIS_LEFT},
+ {")", "parenright", DIKS_PARENTHESIS_RIGHT},
+ {"*", "asterisk", DIKS_ASTERISK},
+ {"+", "plus", DIKS_PLUS_SIGN},
+ {",", "comma", DIKS_COMMA},
+ {"-", "minus", DIKS_MINUS_SIGN},
+ {".", "period", DIKS_PERIOD},
+ {"/", "slash", DIKS_SLASH},
+ {"0", "0", DIKS_0},
+ {"1", "1", DIKS_1},
+ {"2", "2", DIKS_2},
+ {"3", "3", DIKS_3},
+ {"4", "4", DIKS_4},
+ {"5", "5", DIKS_5},
+ {"6", "6", DIKS_6},
+ {"7", "7", DIKS_7},
+ {"8", "8", DIKS_8},
+ {"9", "9", DIKS_9},
+ {":", "colon", DIKS_COLON},
+ {";", "semicolon", DIKS_SEMICOLON},
+ {"<", "less", DIKS_LESS_THAN_SIGN},
+ {"=", "equal", DIKS_EQUALS_SIGN},
+ {">", "greater", DIKS_GREATER_THAN_SIGN},
+ {"?", "question", DIKS_QUESTION_MARK},
+ {"@", "at", DIKS_AT},
+ {"A", "A", DIKS_CAPITAL_A },
+ {"B", "B", DIKS_CAPITAL_B },
+ {"C", "C", DIKS_CAPITAL_C },
+ {"D", "D", DIKS_CAPITAL_D },
+ {"E", "E", DIKS_CAPITAL_E },
+ {"F", "F", DIKS_CAPITAL_F },
+ {"G", "G", DIKS_CAPITAL_G },
+ {"H", "H", DIKS_CAPITAL_H },
+ {"I", "I", DIKS_CAPITAL_I },
+ {"J", "J", DIKS_CAPITAL_J },
+ {"K", "K", DIKS_CAPITAL_K },
+ {"L", "L", DIKS_CAPITAL_L },
+ {"M", "M", DIKS_CAPITAL_M },
+ {"N", "N", DIKS_CAPITAL_N },
+ {"O", "O", DIKS_CAPITAL_O },
+ {"P", "P", DIKS_CAPITAL_P },
+ {"Q", "Q", DIKS_CAPITAL_Q },
+ {"R", "R", DIKS_CAPITAL_R },
+ {"S", "S", DIKS_CAPITAL_S },
+ {"T", "T", DIKS_CAPITAL_T },
+ {"U", "U", DIKS_CAPITAL_U },
+ {"V", "V", DIKS_CAPITAL_V },
+ {"W", "W", DIKS_CAPITAL_W },
+ {"X", "X", DIKS_CAPITAL_X },
+ {"Y", "Y", DIKS_CAPITAL_Y },
+ {"Z", "Z", DIKS_CAPITAL_Z },
+ {"[", "bracketleft", DIKS_SQUARE_BRACKET_LEFT },
+ {"\\", "backslash", DIKS_BACKSLASH },
+ {"]", "bracketright", DIKS_SQUARE_BRACKET_RIGHT },
+ {"^", "asciicircum", DIKS_CIRCUMFLEX_ACCENT },
+ {"_", "underscore", DIKS_UNDERSCORE },
+ {"`", "grave", DIKS_GRAVE_ACCENT},
+ {"a", "a", DIKS_SMALL_A },
+ {"b","b", DIKS_SMALL_B },
+ {"c","c", DIKS_SMALL_C },
+ {"d","d", DIKS_SMALL_D },
+ {"e","e", DIKS_SMALL_E },
+ {"f","f", DIKS_SMALL_F },
+ {"g","g", DIKS_SMALL_G },
+ {"h","h", DIKS_SMALL_H },
+ {"i","i", DIKS_SMALL_I },
+ {"j","j", DIKS_SMALL_J },
+ {"k","k", DIKS_SMALL_K },
+ {"l","l", DIKS_SMALL_L },
+ {"m","m", DIKS_SMALL_M },
+ {"n","n", DIKS_SMALL_N },
+ {"o", "o", DIKS_SMALL_O },
+ {"p", "p", DIKS_SMALL_P },
+ {"q", "q", DIKS_SMALL_Q },
+ {"r", "r", DIKS_SMALL_R },
+ {"s", "s", DIKS_SMALL_S },
+ {"t", "t", DIKS_SMALL_T },
+ {"u", "u", DIKS_SMALL_U },
+ {"v", "v", DIKS_SMALL_V },
+ {"w", "w", DIKS_SMALL_W },
+ {"x", "x", DIKS_SMALL_X },
+ {"y", "y", DIKS_SMALL_Y },
+ {"z", "z", DIKS_SMALL_Z },
+ {"{", "braceleft",DIKS_CURLY_BRACKET_LEFT },
+ {"|", "bar", DIKS_VERTICAL_BAR },
+ {"}", "braceright", DIKS_CURLY_BRACKET_RIGHT },
+ {"~", "asciitilde", DIKS_TILDE },
+ {"\177", "Delete", DIKS_DELETE },
+ {"", "Left", DIKS_CURSOR_LEFT },
+ {"", "Right", DIKS_CURSOR_RIGHT},
+ {"", "Up", DIKS_CURSOR_UP},
+ {"", "Down", DIKS_CURSOR_DOWN},
+ {"", "Insert", DIKS_INSERT},
+ {"", "Home", DIKS_HOME},
+ {"", "End", DIKS_END},
+ {"", "Page_Up", DIKS_PAGE_UP},
+ {"", "Page_Down", DIKS_PAGE_DOWN},
+ {"", "Print", DIKS_PRINT},
+ {"", "Pause", DIKS_PAUSE},
+ /* ok */
+ {"", "Select",DIKS_SELECT},
+ /* goto */
+ {"", "Clear", DIKS_CLEAR},
+ /* power */
+ /* power 2 */
+ /* option */
+ {"", "Menu",DIKS_MENU},
+ {"", "Help",DIKS_HELP},
+ /* info */
+ /* time */
+ /* vendor */
+ /* archive */
+ /* program */
+ /* channel */
+ /* favorites */
+ /* hasta next */
+ {"", "Next",DIKS_NEXT},
+ {"", "Begin",DIKS_BEGIN},
+ /* digits */
+ /* teen */
+ /* twen */
+ {"", "Break", DIKS_BREAK},
+ /* exit */
+ /* setup */
+ {"", "upleftcorner", DIKS_CURSOR_LEFT_UP },
+ {"", "lowleftcorner", DIKS_CURSOR_LEFT_DOWN },
+ {"", "uprightcorner", DIKS_CURSOR_UP_RIGHT },
+ {"", "lowrightcorner",DIKS_CURSOR_DOWN_RIGHT },
+ {"", "F1",DIKS_F1},
+ {"", "F2",DIKS_F2},
+ {"", "F3",DIKS_F3},
+ {"", "F4",DIKS_F4},
+ {"", "F5",DIKS_F5},
+ {"", "F6",DIKS_F6},
+ {"", "F7",DIKS_F7},
+ {"", "F8",DIKS_F8},
+ {"", "F9",DIKS_F9},
+ {"", "F10",DIKS_F10},
+ {"", "F11",DIKS_F11},
+ {"", "F12",DIKS_F12},
+ /* this are only mapped to one, not left right */
+ {"", "Shift_L", DIKS_SHIFT},
+ /*{"Shift_R",0xFFE2},*/
+ {"", "Control_L", DIKS_CONTROL},
+ /*{"Control_R",0xFFE4},*/
+ {"", "Meta_L", DIKS_META},
+ /* {"Meta_R",0xFFE8},*/
+ {"", "Alt_L", DIKS_ALT},
+ {"", "Alt_R", DIKS_ALTGR},
+ {"", "Super_L", DIKS_SUPER},
+ /*{"Super_R",0xFFEC},*/
+ {"", "Hyper_L", DIKS_HYPER},
+ /*{"Hyper_R",0xFFEE},*/
+
+ {"", "Caps_Lock", DIKS_CAPS_LOCK},
+ {"", "Num_Lock", DIKS_NUM_LOCK},
+ {"", "Scroll_Lock", DIKS_SCROLL_LOCK},
+ /* not included the dead keys */
+ /* not included the custom keys */
+ {"", "VoidSymbol", DIKS_NULL}
+};
+static int _ecore_directfb_key_symbols_count = sizeof(_ecore_directfb_key_symbols)/sizeof(Ecore_DirectFB_Key_Symbols);
--- /dev/null
+#ifndef _ECORE_DIRECTFB_PRIVATE_H
+#define _ECORE_DIRECTFB_PRIVATE_H
+/* eina_log related things */
+
+extern int _ecore_directfb_log_dom;
+
+#ifdef ECORE_DIRECTFB_DEFAULT_LOG_COLOR
+#undef ECORE_DIRECTFB_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_DIRECTFB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_directfb_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_directfb_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_directfb_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_directfb_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_directfb_log_dom, __VA_ARGS__)
+
+/* macro for a safe call to DirectFB functions */
+#define DFBCHECK(x...) \
+ { \
+ _err = x; \
+ if (_err != DFB_OK) { \
+ CRIT("%s <%d>:\n\t", __FILE__, __LINE__ ); \
+ DirectFBErrorFatal( #x, _err ); \
+ } \
+ }
+
+struct keymap
+{
+ char *name;
+ char *string;
+};
+#endif
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef _ECORE_EVAS_H
+#define _ECORE_EVAS_H
+
+#include <Evas.h>
+#include <Ecore_Getopt.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_EVAS_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_EVAS_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+/**
+ * @file Ecore_Evas.h
+ * @brief Evas wrapper functions
+ */
+
+/* FIXME:
+ * to do soon:
+ * - iconfication api needs to work
+ * - maximization api needs to work
+ * - document all calls
+ *
+ * later:
+ * - buffer back-end that renders to an evas_image_object ???
+ * - qt back-end ???
+ * - dfb back-end ??? (dfb's threads make this REALLY HARD)
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* these are dummy and just tell u what API levels ecore_evas supports - not if
+ * the actual support is compiled in. you need to query for that separately.
+ */
+#define HAVE_ECORE_EVAS_X 1
+#define HAVE_ECORE_EVAS_FB 1
+#define HAVE_ECORE_EVAS_X11_GL 1
+#define HAVE_ECORE_EVAS_X11_16 1
+#define HAVE_ECORE_EVAS_DIRECTFB 1
+#define HAVE_ECORE_EVAS_WIN32 1
+#define HAVE_ECORE_EVAS_COCOA 1
+#define HAVE_ECORE_EVAS_SDL 1
+#define HAVE_ECORE_EVAS_WINCE 1
+
+typedef enum _Ecore_Evas_Engine_Type
+{
+ ECORE_EVAS_ENGINE_SOFTWARE_BUFFER,
+ ECORE_EVAS_ENGINE_SOFTWARE_XLIB,
+ ECORE_EVAS_ENGINE_XRENDER_X11,
+ ECORE_EVAS_ENGINE_OPENGL_X11,
+ ECORE_EVAS_ENGINE_SOFTWARE_XCB,
+ ECORE_EVAS_ENGINE_XRENDER_XCB,
+ ECORE_EVAS_ENGINE_SOFTWARE_GDI,
+ ECORE_EVAS_ENGINE_SOFTWARE_DDRAW,
+ ECORE_EVAS_ENGINE_DIRECT3D,
+ ECORE_EVAS_ENGINE_OPENGL_GLEW,
+ ECORE_EVAS_ENGINE_COCOA,
+ ECORE_EVAS_ENGINE_SOFTWARE_SDL,
+ ECORE_EVAS_ENGINE_DIRECTFB,
+ ECORE_EVAS_ENGINE_SOFTWARE_FB,
+ ECORE_EVAS_ENGINE_SOFTWARE_16_X11,
+ ECORE_EVAS_ENGINE_SOFTWARE_16_DDRAW,
+ ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE,
+ ECORE_EVAS_ENGINE_OPENGL_SDL
+} Ecore_Evas_Engine_Type;
+
+typedef enum _Ecore_Evas_Avoid_Damage_Type
+{
+ ECORE_EVAS_AVOID_DAMAGE_NONE = 0,
+ ECORE_EVAS_AVOID_DAMAGE_EXPOSE = 1,
+ ECORE_EVAS_AVOID_DAMAGE_BUILT_IN = 2
+} Ecore_Evas_Avoid_Damage_Type;
+
+typedef enum _Ecore_Evas_Object_Associate_Flags
+{
+ ECORE_EVAS_OBJECT_ASSOCIATE_BASE = 0,
+ ECORE_EVAS_OBJECT_ASSOCIATE_STACK = 1 << 0,
+ ECORE_EVAS_OBJECT_ASSOCIATE_LAYER = 1 << 1,
+ ECORE_EVAS_OBJECT_ASSOCIATE_DEL = 1 << 2
+} Ecore_Evas_Object_Associate_Flags;
+
+#ifndef _ECORE_X_H
+#define _ECORE_X_WINDOW_PREDEF
+typedef unsigned int Ecore_X_Window;
+#endif
+
+#ifndef _ECORE_DIRECTFB_H
+#define _ECORE_DIRECTFB_WINDOW_PREDEF
+typedef struct _Ecore_DirectFB_Window Ecore_DirectFB_Window;
+#endif
+
+#ifndef __ECORE_WIN32_H__
+typedef struct _Ecore_Win32_Window Ecore_Win32_Window;
+#endif
+
+#ifndef __ECORE_WINCE_H__
+typedef void Ecore_WinCE_Window;
+#endif
+
+#ifndef _ECORE_EVAS_PRIVATE_H
+/* basic data types */
+typedef struct _Ecore_Evas Ecore_Evas;
+#endif
+
+#include <Ecore_Input.h>
+
+/* module setup/shutdown calls */
+
+EAPI int ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine);
+
+EAPI int ecore_evas_init(void);
+EAPI int ecore_evas_shutdown(void);
+
+EAPI void ecore_evas_app_comp_sync_set(int do_sync);
+EAPI int ecore_evas_app_comp_sync_get(void);
+
+EAPI Eina_List *ecore_evas_engines_get(void);
+EAPI void ecore_evas_engines_free(Eina_List *engines);
+EAPI Ecore_Evas *ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options);
+
+
+/* engine/target specific init calls */
+EAPI Ecore_Evas *ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_evas_software_x11_window_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win);
+
+#define ECORE_EVAS_GL_X11_OPT_NONE 0
+#define ECORE_EVAS_GL_X11_OPT_INDIRECT 1
+#define ECORE_EVAS_GL_X11_OPT_LAST 2
+
+EAPI Ecore_Evas *ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_Evas *ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h, const int *opt);
+EAPI Ecore_X_Window ecore_evas_gl_x11_window_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win);
+EAPI void ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e));
+
+EAPI Ecore_Evas *ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win);
+
+EAPI Ecore_Evas *ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win);
+
+EAPI Ecore_Evas *ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h);
+
+EAPI Ecore_Evas *ecore_evas_directfb_new(const char *disp_name, int windowed, int x, int y, int w, int h);
+EAPI Ecore_DirectFB_Window *ecore_evas_directfb_window_get(const Ecore_Evas *ee);
+
+EAPI Ecore_Evas *ecore_evas_buffer_new(int w, int h);
+EAPI const void *ecore_evas_buffer_pixels_get(Ecore_Evas *ee);
+
+EAPI Evas_Object *ecore_evas_object_image_new(Ecore_Evas *ee_target);
+
+EAPI Ecore_Evas *ecore_evas_software_gdi_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_software_ddraw_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_software_16_ddraw_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_direct3d_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_gl_glew_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Win32_Window *ecore_evas_win32_window_get(const Ecore_Evas *ee);
+
+EAPI Ecore_Evas *ecore_evas_sdl_new(const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha);
+EAPI Ecore_Evas *ecore_evas_sdl16_new(const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha);
+EAPI Ecore_Evas *ecore_evas_gl_sdl_new(const char* name, int w, int h, int fullscreen, int noframe);
+
+EAPI Ecore_Evas *ecore_evas_software_wince_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_software_wince_fb_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_software_wince_gapi_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_software_wince_ddraw_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_Evas *ecore_evas_software_wince_gdi_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI Ecore_WinCE_Window *ecore_evas_software_wince_window_get(const Ecore_Evas *ee);
+
+EAPI Ecore_Evas *ecore_evas_cocoa_new(const char* name, int w, int h);
+
+/* generic manipulation calls */
+EAPI const char *ecore_evas_engine_name_get(const Ecore_Evas *ee);
+EAPI Ecore_Evas *ecore_evas_ecore_evas_get(const Evas *e);
+EAPI void ecore_evas_free(Ecore_Evas *ee);
+EAPI void *ecore_evas_data_get(const Ecore_Evas *ee, const char *key);
+EAPI void ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data);
+EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_move_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_show_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_hide_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_sticky_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_unsticky_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_pre_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_post_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI void ecore_evas_callback_pre_free_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+EAPI Evas *ecore_evas_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_move(Ecore_Evas *ee, int x, int y);
+EAPI void ecore_evas_managed_move(Ecore_Evas *ee, int x, int y);
+EAPI void ecore_evas_resize(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
+EAPI void ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h);
+EAPI void ecore_evas_rotation_set(Ecore_Evas *ee, int rot);
+EAPI void ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot);
+EAPI int ecore_evas_rotation_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_shaped_set(Ecore_Evas *ee, int shaped);
+EAPI int ecore_evas_shaped_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_alpha_set(Ecore_Evas *ee, int alpha);
+EAPI int ecore_evas_alpha_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_transparent_set(Ecore_Evas *ee, int transparent);
+EAPI int ecore_evas_transparent_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_show(Ecore_Evas *ee);
+EAPI void ecore_evas_hide(Ecore_Evas *ee);
+EAPI int ecore_evas_visibility_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_raise(Ecore_Evas *ee);
+EAPI void ecore_evas_lower(Ecore_Evas *ee);
+EAPI void ecore_evas_activate(Ecore_Evas *ee);
+EAPI void ecore_evas_title_set(Ecore_Evas *ee, const char *t);
+EAPI const char *ecore_evas_title_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c);
+EAPI void ecore_evas_name_class_get(const Ecore_Evas *ee, const char **n, const char **c);
+EAPI void ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_min_get(const Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_max_get(const Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_base_get(const Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h);
+EAPI void ecore_evas_size_step_get(const Ecore_Evas *ee, int *w, int *h);
+EAPI void ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y);
+EAPI void ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y);
+EAPI void ecore_evas_cursor_get(const Ecore_Evas *ee, Evas_Object **obj, int *layer, int *hot_x, int *hot_y);
+EAPI void ecore_evas_layer_set(Ecore_Evas *ee, int layer);
+EAPI int ecore_evas_layer_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_focus_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_focus_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_iconified_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_iconified_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_borderless_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_borderless_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_override_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_override_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_maximized_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_maximized_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, int on);
+EAPI int ecore_evas_fullscreen_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_avoid_damage_set(Ecore_Evas *ee, Ecore_Evas_Avoid_Damage_Type on);
+EAPI Ecore_Evas_Avoid_Damage_Type ecore_evas_avoid_damage_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_withdrawn_set(Ecore_Evas *ee, int withdrawn);
+EAPI int ecore_evas_withdrawn_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_sticky_set(Ecore_Evas *ee, int sticky);
+EAPI int ecore_evas_sticky_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_ignore_events_set(Ecore_Evas *ee, int ignore);
+EAPI int ecore_evas_ignore_events_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_manual_render_set(Ecore_Evas *ee, int manual_render);
+EAPI int ecore_evas_manual_render_get(const Ecore_Evas *ee);
+EAPI void ecore_evas_manual_render(Ecore_Evas *ee);
+EAPI void ecore_evas_comp_sync_set(Ecore_Evas *ee, int do_sync);
+EAPI int ecore_evas_comp_sync_get(const Ecore_Evas *ee);
+
+EAPI Ecore_Window ecore_evas_window_get(const Ecore_Evas *ee);
+
+
+EAPI int ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags);
+EAPI int ecore_evas_object_dissociate(Ecore_Evas *ee, Evas_Object *obj);
+EAPI Evas_Object *ecore_evas_object_associate_get(const Ecore_Evas *ee);
+
+/* helper function to be used with ECORE_GETOPT_CALLBACK_*() */
+EAPI unsigned char ecore_getopt_callback_ecore_evas_list_engines(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_X
+ECORE_X_INC = -I$(top_srcdir)/src/lib/ecore_x @x_cflags@ @XRENDER_CFLAGS@ @XCB_CFLAGS@ @XCB_RENDER_CFLAGS@
+ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la @x_libs@ @XRENDER_LIBS@ @XCB_LIBS@ @XCB_RENDER_LIBS@
+else
+ECORE_X_INC =
+ECORE_X_LIB =
+endif
+
+if BUILD_ECORE_FB
+ECORE_FB_INC = -I$(top_srcdir)/src/lib/ecore_fb
+ECORE_FB_LIB = $(top_builddir)/src/lib/ecore_fb/libecore_fb.la
+else
+ECORE_FB_INC =
+ECORE_FB_LIB =
+endif
+
+if BUILD_ECORE_DIRECTFB
+ECORE_DIRECTFB_INC = -I$(top_srcdir)/src/lib/ecore_directfb -I@DIRECTFB_CFLAGS@
+ECORE_DIRECTFB_LIB = $(top_builddir)/src/lib/ecore_directfb/libecore_directfb.la
+else
+ECORE_DIRECTFB_INC =
+ECORE_DIRECTFB_LIB =
+endif
+
+if BUILD_ECORE_WIN32
+ECORE_WIN32_INC = -I$(top_srcdir)/src/lib/ecore_win32
+ECORE_WIN32_LIB = $(top_builddir)/src/lib/ecore_win32/libecore_win32.la
+else
+ECORE_WIN32_INC =
+ECORE_WIN32_LIB =
+endif
+
+if BUILD_ECORE_SDL
+ECORE_SDL_INC = -I$(top_srcdir)/src/lib/ecore_sdl @SDL_CFLAGS@
+ECORE_SDL_LIB = $(top_builddir)/src/lib/ecore_sdl/libecore_sdl.la
+ECORE_SDL_LIBADD = @SDL_LIBS@ $(ECORE_SDL_LIB)
+else
+ECORE_SDL_INC =
+ECORE_SDL_LIB =
+ECORE_SDL_LIBADD =
+endif
+
+if BUILD_ECORE_COCOA
+ECORE_COCOA_INC = -I$(top_srcdir)/src/lib/ecore_cocoa -xobjective-c
+ECORE_COCOA_LIB = $(top_builddir)/src/lib/ecore_cocoa/libecore_cocoa.la
+else
+ECORE_COCOA_INC =
+ECORE_COCOA_LIB =
+endif
+
+if BUILD_ECORE_WINCE
+ECORE_WINCE_INC = -I$(top_srcdir)/src/lib/ecore_wince
+ECORE_WINCE_LIB = $(top_builddir)/src/lib/ecore_wince/libecore_wince.la
+else
+ECORE_WINCE_INC =
+ECORE_WINCE_LIB =
+endif
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_evas \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_srcdir)/src/lib/ecore_input_evas \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_evas \
+-I$(top_builddir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore_input_evas \
+@EFL_ECORE_EVAS_BUILD@ \
+$(ECORE_X_INC) \
+$(ECORE_FB_INC) \
+$(ECORE_DIRECTFB_INC) \
+$(ECORE_WIN32_INC) \
+$(ECORE_SDL_INC) \
+$(ECORE_COCOA_INC) \
+$(ECORE_WINCE_INC) \
+@EVAS_CFLAGS@ \
+@XCB_CFLAGS@ \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+AM_CFLAGS = @WIN32_CFLAGS@
+
+if BUILD_ECORE_EVAS
+
+lib_LTLIBRARIES = libecore_evas.la
+include_HEADERS = \
+Ecore_Evas.h
+
+libecore_evas_la_SOURCES = \
+ecore_evas.c \
+ecore_evas_util.c \
+ecore_evas_x.c \
+ecore_evas_fb.c \
+ecore_evas_buffer.c \
+ecore_evas_directfb.c \
+ecore_evas_win32.c \
+ecore_evas_sdl.c \
+ecore_evas_cocoa.c \
+ecore_evas_wince.c
+
+libecore_evas_la_LIBADD = \
+$(ECORE_X_LIB) \
+$(ECORE_FB_LIB) \
+$(ECORE_DIRECTFB_LIB) \
+$(ECORE_WIN32_LIB) \
+$(ECORE_SDL_LIB) \
+$(ECORE_SDL_LIBADD) \
+$(ECORE_COCOA_LIB) \
+$(ECORE_WINCE_LIB) \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+$(top_builddir)/src/lib/ecore_input_evas/libecore_input_evas.la \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@EVAS_LIBS@ \
+@EINA_LIBS@ \
+@EVIL_LIBS@
+
+libecore_evas_la_LDFLAGS = @cocoa_ldflags@ -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_evas_release_info@
+
+endif
+
+EXTRA_DIST = \
+ecore_evas_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#ifndef _MSC_VER
+# include <unistd.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Input.h"
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+int _ecore_evas_log_dom = -1;
+static int _ecore_evas_init_count = 0;
+static Ecore_Fd_Handler *_ecore_evas_async_events_fd = NULL;
+static int _ecore_evas_async_events_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+
+static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL;
+static Ecore_Evas *ecore_evases = NULL;
+static int _ecore_evas_fps_debug = 0;
+
+static int
+_ecore_evas_idle_enter(void *data __UNUSED__)
+{
+ Ecore_Evas *ee;
+ double t1 = 0.0;
+ double t2 = 0.0;
+ int rend = 0;
+
+ if (!ecore_evases) return 1;
+ if (_ecore_evas_fps_debug)
+ {
+ t1 = ecore_time_get();
+ }
+ EINA_INLIST_FOREACH(ecore_evases, ee)
+ {
+ if (!ee->manual_render)
+ {
+ if (ee->engine.func->fn_render)
+ rend |= ee->engine.func->fn_render(ee);
+ }
+ }
+ if (_ecore_evas_fps_debug)
+ {
+ t2 = ecore_time_get();
+ if (rend)
+ _ecore_evas_fps_debug_rendertime_add(t2 - t1);
+ }
+ return 1;
+}
+
+/**
+ * Query if a particular renginering engine target has support
+ * @param engine The engine to check support for
+ * @return 1 if the particualr engine is supported, 0 if it is not
+ *
+ * Query if engine @param engine is supported by ecore_evas. 1 is returned if
+ * it is, and 0 is returned if it is not supported.
+ */
+EAPI int
+ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
+{
+ switch (engine)
+ {
+ case ECORE_EVAS_ENGINE_SOFTWARE_BUFFER:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_XLIB:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_XLIB
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_XRENDER_X11:
+#ifdef BUILD_ECORE_EVAS_XRENDER_X11
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_OPENGL_X11:
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_XCB:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_XRENDER_XCB:
+#ifdef BUILD_ECORE_EVAS_XRENDER_XCB
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_GDI:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_DDRAW:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_DIRECT3D:
+#ifdef BUILD_ECORE_EVAS_DIRECT3D
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_OPENGL_GLEW:
+#ifdef BUILD_ECORE_EVAS_OPENGL_GLEW
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_SDL:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_OPENGL_SDL:
+#ifdef BUILD_ECORE_EVAS_OPENGL_SDL
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_DIRECTFB:
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_FB:
+#ifdef BUILD_ECORE_EVAS_FB
+ return 1;
+#else
+ return 0;
+#endif
+
+ case ECORE_EVAS_ENGINE_SOFTWARE_16_X11:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_X11
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_16_DDRAW:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE:
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+ return 1;
+#else
+ return 0;
+#endif
+ case ECORE_EVAS_ENGINE_COCOA:
+#ifdef BUILD_ECORE_EVAS_COCOA
+ return 1;
+#else
+ return 0;
+#endif
+ default:
+ return 0;
+ break;
+ };
+}
+
+/**
+ * Init the Evas system.
+ * @return greater than 0 on success, 0 on failure
+ *
+ * Set up the Evas wrapper system. Init Evas and Ecore libraries.
+ */
+EAPI int
+ecore_evas_init(void)
+{
+ int fd;
+
+ if (++_ecore_evas_init_count != 1)
+ return _ecore_evas_init_count;
+
+ if (!evas_init())
+ return --_ecore_evas_init_count;
+
+ if (!ecore_init())
+ goto shutdown_evas;
+
+ _ecore_evas_log_dom = eina_log_domain_register("Ecore_Evas", ECORE_EVAS_DEFAULT_LOG_COLOR);
+ if(_ecore_evas_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for Ecore_Evas.");
+ goto shutdown_ecore;
+ }
+
+ fd = evas_async_events_fd_get();
+ if (fd > 0)
+ _ecore_evas_async_events_fd = ecore_main_fd_handler_add(fd,
+ ECORE_FD_READ,
+ _ecore_evas_async_events_fd_handler, NULL,
+ NULL, NULL);
+
+ ecore_evas_idle_enterer =
+ ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
+ if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
+
+ return _ecore_evas_init_count;
+
+ shutdown_ecore:
+ ecore_shutdown();
+ shutdown_evas:
+ evas_shutdown();
+
+ return --_ecore_evas_init_count;
+}
+
+/**
+ * Shut down the Evas system.
+ * @return 0 if ecore evas is fully shut down, or > 0 if it still needs to be shut down
+ *
+ * This closes the Evas wrapper system down. Shut down Evas and Ecore libraries.
+ */
+EAPI int
+ecore_evas_shutdown(void)
+{
+ if (--_ecore_evas_init_count != 0)
+ return _ecore_evas_init_count;
+
+ while (ecore_evases) _ecore_evas_free(ecore_evases);
+
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
+ ecore_idle_enterer_del(ecore_evas_idle_enterer);
+ ecore_evas_idle_enterer = NULL;
+
+#ifdef BUILD_ECORE_EVAS_X11
+ while (_ecore_evas_x_shutdown());
+#endif
+#ifdef BUILD_ECORE_EVAS_WIN32
+ while (_ecore_evas_win32_shutdown());
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+ while (_ecore_evas_fb_shutdown());
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ while (_ecore_evas_buffer_shutdown());
+#endif
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+ while (_ecore_evas_directfb_shutdown());
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+ while (_ecore_evas_wince_shutdown());
+#endif
+ if (_ecore_evas_async_events_fd)
+ ecore_main_fd_handler_del(_ecore_evas_async_events_fd);
+
+ eina_log_domain_unregister(_ecore_evas_log_dom);
+ _ecore_evas_log_dom = -1;
+ ecore_shutdown();
+ evas_shutdown();
+
+ return _ecore_evas_init_count;
+}
+
+int _ecore_evas_app_comp_sync = 1;
+
+EAPI void
+ecore_evas_app_comp_sync_set(int do_sync)
+{
+ _ecore_evas_app_comp_sync = do_sync;
+}
+
+EAPI int
+ecore_evas_app_comp_sync_get(void)
+{
+ return _ecore_evas_app_comp_sync;
+}
+
+struct ecore_evas_engine {
+ const char *name;
+ Ecore_Evas *(*constructor)(int x, int y, int w, int h, const char *extra_options);
+};
+
+/* inline is just to avoid need to ifdef around it */
+static inline const char *
+_ecore_evas_parse_extra_options_str(const char *extra_options, const char *key, char **value)
+{
+ int len = strlen(key);
+
+ while (extra_options)
+ {
+ const char *p;
+
+ if (strncmp(extra_options, key, len) != 0)
+ {
+ extra_options = strchr(extra_options, ';');
+ if (extra_options)
+ extra_options++;
+ continue;
+ }
+
+ extra_options += len;
+ p = strchr(extra_options, ';');
+ if (p)
+ {
+ len = p - extra_options;
+ *value = malloc(len + 1);
+ memcpy(*value, extra_options, len);
+ (*value)[len] = '\0';
+ extra_options = p + 1;
+ }
+ else
+ {
+ *value = strdup(extra_options);
+ extra_options = NULL;
+ }
+ }
+ return extra_options;
+}
+
+/* inline is just to avoid need to ifdef around it */
+static inline const char *
+_ecore_evas_parse_extra_options_uint(const char *extra_options, const char *key, unsigned int *value)
+{
+ int len = strlen(key);
+
+ while (extra_options)
+ {
+ const char *p;
+
+ if (strncmp(extra_options, key, len) != 0)
+ {
+ extra_options = strchr(extra_options, ';');
+ if (extra_options)
+ extra_options++;
+ continue;
+ }
+
+ extra_options += len;
+ *value = strtol(extra_options, NULL, 0);
+
+ p = strchr(extra_options, ';');
+ if (p)
+ extra_options = p + 1;
+ else
+ extra_options = NULL;
+ }
+ return extra_options;
+}
+
+/* inline is just to avoid need to ifdef around it */
+static inline const char *
+_ecore_evas_parse_extra_options_x(const char *extra_options, char **disp_name, unsigned int *parent)
+{
+ _ecore_evas_parse_extra_options_str(extra_options, "display=", disp_name);
+ _ecore_evas_parse_extra_options_uint(extra_options, "parent=", parent);
+ return extra_options;
+}
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+static Ecore_Evas *
+_ecore_evas_constructor_software_x11(int x, int y, int w, int h, const char *extra_options)
+{
+ unsigned int parent = 0;
+ char *disp_name = NULL;
+ Ecore_Evas *ee;
+
+ _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
+ ee = ecore_evas_software_x11_new(disp_name, parent, x, y, w, h);
+ free(disp_name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_COCOA
+static Ecore_Evas *
+_ecore_evas_constructor_cocoa(int x, int y, int w, int h, const char *extra_options)
+{
+ char *name = NULL;
+ Ecore_Evas *ee;
+
+ _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
+ ee = ecore_evas_cocoa_new(name, w, h);
+ free(name);
+
+ if (ee) ecore_evas_move(ee, x, y);
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_XRENDER_X11
+static Ecore_Evas *
+_ecore_evas_constructor_xrender_x11(int x, int y, int w, int h, const char *extra_options)
+{
+ unsigned int parent = 0;
+ char *disp_name = NULL;
+ Ecore_Evas *ee;
+
+ _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
+ ee = ecore_evas_xrender_x11_new(disp_name, parent, x, y, w, h);
+ free(disp_name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+static Ecore_Evas *
+_ecore_evas_constructor_opengl_x11(int x, int y, int w, int h, const char *extra_options)
+{
+ Ecore_X_Window parent = 0;
+ char *disp_name = NULL;
+ Ecore_Evas *ee;
+
+ _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
+ ee = ecore_evas_gl_x11_new(disp_name, parent, x, y, w, h);
+ free(disp_name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_X11
+static Ecore_Evas *
+_ecore_evas_constructor_software_16_x11(int x, int y, int w, int h, const char *extra_options)
+{
+ Ecore_X_Window parent = 0;
+ char *disp_name = NULL;
+ Ecore_Evas *ee;
+
+ _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
+ ee = ecore_evas_software_x11_16_new(disp_name, parent, x, y, w, h);
+ free(disp_name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
+static Ecore_Evas *
+_ecore_evas_constructor_sdl(int x __UNUSED__, int y __UNUSED__, int w, int h, const char *extra_options)
+{
+ Ecore_Evas *ee;
+ unsigned int fullscreen = 0, hwsurface = 0, noframe = 0, alpha = 0;
+ char *name = NULL;
+
+ _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
+ _ecore_evas_parse_extra_options_uint(extra_options, "fullscreen=", &fullscreen);
+ _ecore_evas_parse_extra_options_uint(extra_options, "hwsurface=", &hwsurface);
+ _ecore_evas_parse_extra_options_uint(extra_options, "alpha=", &alpha);
+
+ ee = ecore_evas_sdl_new(name, w, h, fullscreen, hwsurface, noframe, alpha);
+ free(name);
+
+ return ee;
+}
+
+static Ecore_Evas *
+_ecore_evas_constructor_sdl16(int x __UNUSED__, int y __UNUSED__, int w, int h, const char *extra_options)
+{
+ Ecore_Evas *ee;
+ unsigned int fullscreen = 0, hwsurface = 0, noframe = 0, alpha = 0;
+ char *name = NULL;
+
+ _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
+ _ecore_evas_parse_extra_options_uint(extra_options, "fullscreen=", &fullscreen);
+ _ecore_evas_parse_extra_options_uint(extra_options, "hwsurface=", &hwsurface);
+ _ecore_evas_parse_extra_options_uint(extra_options, "alpha=", &alpha);
+
+ ee = ecore_evas_sdl16_new(name, w, h, fullscreen, hwsurface, noframe, alpha);
+ free(name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_SDL
+static Ecore_Evas *
+_ecore_evas_constructor_opengl_sdl(int x __UNUSED__, int y __UNUSED__, int w, int h, const char *extra_options)
+{
+ Ecore_Evas *ee;
+ unsigned int fullscreen = 0, noframe = 0;
+ char *name = NULL;
+
+ _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
+ _ecore_evas_parse_extra_options_uint(extra_options, "fullscreen=", &fullscreen);
+ _ecore_evas_parse_extra_options_uint(extra_options, "noframe=", &noframe);
+
+ ee = ecore_evas_gl_sdl_new(name, w, h, fullscreen, noframe);
+ free(name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+static Ecore_Evas *
+_ecore_evas_constructor_directfb(int x, int y, int w, int h, const char *extra_options)
+{
+ Ecore_Evas *ee;
+ char *disp_name = NULL;
+ unsigned int windowed = 1;
+
+ _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
+ _ecore_evas_parse_extra_options_uint(extra_options, "windowed=", &windowed);
+
+ ee = ecore_evas_directfb_new(disp_name, windowed, x, y, w, h);
+ free(disp_name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_FB
+static Ecore_Evas *
+_ecore_evas_constructor_fb(int x __UNUSED__, int y __UNUSED__, int w, int h, const char *extra_options)
+{
+ Ecore_Evas *ee;
+ char *disp_name = NULL;
+ unsigned int rotation = 0;
+
+ _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
+ _ecore_evas_parse_extra_options_uint(extra_options, "rotation=", &rotation);
+
+ ee = ecore_evas_fb_new(disp_name, rotation, w, h);
+ free(disp_name);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
+static Ecore_Evas *
+_ecore_evas_constructor_software_gdi(int x, int y, int w, int h, const char *extra_options)
+{
+ return ecore_evas_software_gdi_new(NULL, x, y, w, h);
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
+static Ecore_Evas *
+_ecore_evas_constructor_software_ddraw(int x, int y, int w, int h, const char *extra_options)
+{
+ return ecore_evas_software_ddraw_new(NULL, x, y, w, h);
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_DIRECT3D
+static Ecore_Evas *
+_ecore_evas_constructor_direct3d(int x, int y, int w, int h, const char *extra_options)
+{
+ return ecore_evas_direct3d_new(NULL, x, y, w, h);
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_GLEW
+static Ecore_Evas *
+_ecore_evas_constructor_opengl_glew(int x, int y, int w, int h, const char *extra_options)
+{
+ return ecore_evas_gl_glew_new(NULL, x, y, w, h);
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW
+static Ecore_Evas *
+_ecore_evas_constructor_software_16_ddraw(int x, int y, int w, int h, const char *extra_options)
+{
+ return ecore_evas_software_16_ddraw_new(NULL, x, y, w, h);
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+static Ecore_Evas *
+_ecore_evas_constructor_software_16_wince(int x, int y, int w, int h, const char *extra_options __UNUSED__)
+{
+ return ecore_evas_software_wince_new(NULL, x, y, w, h);
+}
+
+static Ecore_Evas *
+_ecore_evas_constructor_software_16_wince_fb(int x, int y, int w, int h, const char *extra_options __UNUSED__)
+{
+ return ecore_evas_software_wince_fb_new(NULL, x, y, w, h);
+}
+
+static Ecore_Evas *
+_ecore_evas_constructor_software_16_wince_gapi(int x, int y, int w, int h, const char *extra_options __UNUSED__)
+{
+ return ecore_evas_software_wince_gapi_new(NULL, x, y, w, h);
+}
+
+static Ecore_Evas *
+_ecore_evas_constructor_software_16_wince_gdi(int x, int y, int w, int h, const char *extra_options __UNUSED__)
+{
+ return ecore_evas_software_wince_gdi_new(NULL, x, y, w, h);
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+static Ecore_Evas *
+_ecore_evas_constructor_buffer(int x __UNUSED__, int y __UNUSED__, int w, int h, const char *extra_options __UNUSED__)
+{
+ return ecore_evas_buffer_new(w, h);
+}
+#endif
+
+/* note: keep sorted by priority, highest first */
+static const struct ecore_evas_engine _engines[] = {
+ /* unix */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+ {"software_x11", _ecore_evas_constructor_software_x11},
+#endif
+#ifdef BUILD_ECORE_EVAS_XRENDER_X11
+ {"xrender_x11", _ecore_evas_constructor_xrender_x11},
+#endif
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+ {"opengl_x11", _ecore_evas_constructor_opengl_x11},
+#endif
+#ifdef BUILD_ECORE_EVAS_XRENDER_XCB
+ {"xrender_xcb", _ecore_evas_constructor_xrender_x11},
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_X11
+ {"software_16_x11", _ecore_evas_constructor_software_16_x11},
+#endif
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+ {"directfb", _ecore_evas_constructor_directfb},
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+ {"fb", _ecore_evas_constructor_fb},
+#endif
+
+ /* windows */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
+ {"software_gdi", _ecore_evas_constructor_software_gdi},
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
+ {"software_ddraw", _ecore_evas_constructor_software_ddraw},
+#endif
+#ifdef BUILD_ECORE_EVAS_DIRECT3D
+ {"direct3d", _ecore_evas_constructor_direct3d},
+#endif
+#ifdef BUILD_ECORE_EVAS_OPENGL_GLEW
+ {"opengl_glew", _ecore_evas_constructor_opengl_glew},
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW
+ {"software_16_ddraw", _ecore_evas_constructor_software_16_ddraw},
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+ {"software_16_wince", _ecore_evas_constructor_software_16_wince},
+ {"software_16_wince_fb", _ecore_evas_constructor_software_16_wince_fb},
+ {"software_16_wince_gapi", _ecore_evas_constructor_software_16_wince_gapi},
+ {"software_16_wince_gdi", _ecore_evas_constructor_software_16_wince_gdi},
+#endif
+
+ /* Apple */
+#ifdef BUILD_ECORE_EVAS_COCOA
+ {"cocoa", _ecore_evas_constructor_cocoa},
+#endif
+
+ /* Last chance to have a window */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
+ {"sdl", _ecore_evas_constructor_sdl},
+ {"software_16_sdl", _ecore_evas_constructor_sdl16},
+#endif
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_SDL
+ {"opengl_sdl", _ecore_evas_constructor_opengl_sdl},
+#endif
+
+ /* independent */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ {"buffer", _ecore_evas_constructor_buffer},
+#endif
+ {NULL, NULL}
+};
+
+/**
+ * Returns a list of supported engines names.
+ *
+ * @return newly allocated list with engines names. Engines names
+ * strings are internal and should be considered constants, do not
+ * free them, to avoid problems use ecore_evas_engines_free()
+ */
+EAPI Eina_List *
+ecore_evas_engines_get(void)
+{
+ const struct ecore_evas_engine *itr;
+ Eina_List *lst = NULL;
+
+ for (itr = _engines; itr->name != NULL; itr++)
+ lst = eina_list_append(lst, itr->name);
+
+ return lst;
+}
+
+/**
+ * Free list returned by ecore_evas_engines_get()
+ */
+EAPI void
+ecore_evas_engines_free(Eina_List *engines)
+{
+ eina_list_free(engines);
+}
+
+static Ecore_Evas *
+_ecore_evas_new_auto_discover(int x, int y, int w, int h, const char *extra_options)
+{
+ const struct ecore_evas_engine *itr;
+
+ DBG("auto discover engine");
+
+ for (itr = _engines; itr->constructor != NULL; itr++)
+ {
+ Ecore_Evas *ee = itr->constructor(x, y, w, h, extra_options);
+ if (ee)
+ {
+ INF("auto discovered '%s'", itr->name);
+ return ee;
+ }
+ }
+
+ WRN("could not auto discover.");
+ return NULL;
+}
+
+/**
+ * Creates a new Ecore_Evas based on engine name and common parameters.
+ *
+ * @param engine_name engine name as returned by
+ * ecore_evas_engines_get() or NULL to use environment variable
+ * ECORE_EVAS_ENGINE, that can be undefined and in this case
+ * this call will try to find the first working engine.
+ * @param x horizontal position of window (not supported in all engines)
+ * @param y vertical position of window (not supported in all engines)
+ * @param w width of window
+ * @param h height of window
+ * @param extra_options string with extra parameter, dependent on engines
+ * or NULL. String is usually in the form: 'key1=value1;key2=value2'.
+ * Pay attention that when getting that from shell commands, most
+ * consider ';' as the command terminator, so you need to escape
+ * it or use quotes.
+ *
+ * @return Ecore_Evas instance or NULL if creation failed.
+ */
+EAPI Ecore_Evas *
+ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options)
+{
+ const struct ecore_evas_engine *itr;
+
+ if (!engine_name)
+ {
+ engine_name = getenv("ECORE_EVAS_ENGINE");
+ if (engine_name)
+ DBG("no engine_name provided, using ECORE_EVAS_ENGINE='%s'",
+ engine_name);
+ }
+ if (!engine_name)
+ return _ecore_evas_new_auto_discover(x, y, w, h, extra_options);
+
+ for (itr = _engines; itr->name != NULL; itr++)
+ if (strcmp(itr->name, engine_name) == 0)
+ {
+ INF("using engine '%s', extra_options=%s",
+ engine_name, extra_options ? extra_options : "(null)");
+ return itr->constructor(x, y, w, h, extra_options);
+ }
+
+ WRN("unknown engine '%s'", engine_name);
+ return NULL;
+}
+
+/**
+ * Get the engine name used by this engine.
+ *
+ * should return one of the values in ecore_evas_engines_get(), usually
+ * acceptable by ecore_evas_new().
+ */
+EAPI const char *
+ecore_evas_engine_name_get(const Ecore_Evas *ee)
+{
+ if (!ee)
+ return NULL;
+ return ee->driver;
+}
+
+/**
+ * Return the Ecore_Evas for this Evas
+ *
+ * @param e The Evas to get the Ecore_Evas from
+ * @return The Ecore_Evas that holds this Evas
+ */
+EAPI Ecore_Evas *
+ecore_evas_ecore_evas_get(const Evas *e)
+{
+ return evas_data_attach_get(e);
+}
+
+/**
+ * Free an Ecore_Evas
+ * @param ee The Ecore_Evas to free
+ *
+ * This frees up any memory used by the Ecore_Evas.
+ */
+EAPI void
+ecore_evas_free(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_free");
+ return;
+ }
+ _ecore_evas_free(ee);
+ return;
+}
+
+/**
+ * Retrieve user data associated with an Ecore_Evas.
+ * @param ee The Ecore_Evas to retrieve the user data from.
+ * @param key The key which the user data to be retrieved is associated with.
+ *
+ * This function retrieves user specific data that has been stored within an
+ * Ecore_Evas structure with ecore_evas_data_set().
+ *
+ * @returns NULL on error or no data found, A pointer to the user data on
+ * success.
+ *
+ * @see ecore_evas_data_set
+ */
+EAPI void *
+ecore_evas_data_get(const Ecore_Evas *ee, const char *key)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_data_get");
+ return NULL;
+ }
+
+ if (!key) return NULL;
+ if (!ee->data) return NULL;
+
+ return eina_hash_find(ee->data, key);
+}
+
+/**
+ * Store user data in an Ecore_Evas structure.
+ *
+ * @param ee The Ecore_Evas to store the user data in.
+ * @param key A unique string to associate the user data against. Cannot
+ * be NULL.
+ * @param data A pointer to the user data to store.
+ *
+ * This function associates the @p data with a @p key which is stored by
+ * the Ecore_Evas @p ee. Be aware that a call to ecore_evas_free() will
+ * not free any memory for the associated user data, this is the responsibility
+ * of the caller.
+ *
+ * @see ecore_evas_free
+ */
+EAPI void
+ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_data_set");
+ return;
+ }
+
+ if (!key) return;
+
+ if (ee->data)
+ eina_hash_del(ee->data, key, NULL);
+ if (data)
+ {
+ if (!ee->data)
+ ee->data = eina_hash_string_superfast_new(NULL);
+ eina_hash_add(ee->data, key, data);
+ }
+}
+
+#define IFC(_ee, _fn) if (_ee->engine.func->_fn) {_ee->engine.func->_fn
+#define IFE return;}
+
+/**
+ * Set a callback for Ecore_Evas resize events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is resized.
+ */
+EAPI void
+ecore_evas_callback_resize_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_resize_set");
+ return;
+ }
+ IFC(ee, fn_callback_resize_set) (ee, func);
+ IFE;
+ ee->func.fn_resize = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas move events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is moved.
+ */
+EAPI void
+ecore_evas_callback_move_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_move_set");
+ return;
+ }
+ IFC(ee, fn_callback_move_set) (ee, func);
+ IFE;
+ ee->func.fn_move = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas show events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is shown.
+ */
+EAPI void
+ecore_evas_callback_show_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_show_set");
+ return;
+ }
+ IFC(ee, fn_callback_show_set) (ee, func);
+ IFE;
+ ee->func.fn_show = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas hide events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is hidden.
+ */
+EAPI void
+ecore_evas_callback_hide_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_hide_set");
+ return;
+ }
+ IFC(ee, fn_callback_hide_set) (ee, func);
+ IFE;
+ ee->func.fn_hide = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas delete request events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee gets a delete request.
+ */
+EAPI void
+ecore_evas_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_delete_request_set");
+ return;
+ }
+ IFC(ee, fn_callback_delete_request_set) (ee, func);
+ IFE;
+ ee->func.fn_delete_request = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas destroy events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee is destroyed.
+ */
+EAPI void
+ecore_evas_callback_destroy_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_destroy_set");
+ return;
+ }
+ IFC(ee, fn_callback_destroy_set) (ee, func);
+ IFE;
+ ee->func.fn_destroy = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas focus in events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee gets focus.
+ */
+EAPI void
+ecore_evas_callback_focus_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_focus_in_set");
+ return;
+ }
+ IFC(ee, fn_callback_focus_in_set) (ee, func);
+ IFE;
+ ee->func.fn_focus_in = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas focus out events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee loses focus.
+ */
+EAPI void
+ecore_evas_callback_focus_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_focus_out_set");
+ return;
+ }
+ IFC(ee, fn_callback_focus_out_set) (ee, func);
+ IFE;
+ ee->func.fn_focus_out = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas sticky events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee becomes sticky.
+ */
+EAPI void
+ecore_evas_callback_sticky_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_sticky_set");
+ return;
+ }
+ IFC(ee, fn_callback_sticky_set) (ee, func);
+ IFE;
+ ee->func.fn_sticky = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas un-sticky events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever @p ee becomes un-sticky.
+ */
+EAPI void
+ecore_evas_callback_unsticky_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_unsticky_set");
+ return;
+ }
+ IFC(ee, fn_callback_unsticky_set) (ee, func);
+ IFE;
+ ee->func.fn_unsticky = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse in events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever the mouse enters @p ee.
+ */
+EAPI void
+ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_mouse_in_set");
+ return;
+ }
+ IFC(ee, fn_callback_mouse_in_set) (ee, func);
+ IFE;
+ ee->func.fn_mouse_in = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse out events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called whenever the mouse leaves @p ee.
+ */
+EAPI void
+ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_mouse_out_set");
+ return;
+ }
+ IFC(ee, fn_callback_mouse_out_set) (ee, func);
+ IFE;
+ ee->func.fn_mouse_out = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse pre render events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called just before the evas in @p ee is rendered.
+ */
+EAPI void
+ecore_evas_callback_pre_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_pre_render_set");
+ return;
+ }
+ IFC(ee, fn_callback_pre_render_set) (ee, func);
+ IFE;
+ ee->func.fn_pre_render = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas mouse post render events.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called just after the evas in @p ee is rendered.
+ */
+EAPI void
+ecore_evas_callback_post_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_post_render_set");
+ return;
+ }
+ IFC(ee, fn_callback_post_render_set) (ee, func);
+ IFE;
+ ee->func.fn_post_render = func;
+}
+
+/**
+ * Set a callback for Ecore_Evas pre-free event.
+ * @param ee The Ecore_Evas to set callbacks on
+ * @param func The function to call
+ *
+ * A call to this function will set a callback on an Ecore_Evas, causing
+ * @p func to be called just before the instance @p ee is freed.
+ */
+EAPI void
+ecore_evas_callback_pre_free_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_callback_pre_free_set");
+ return;
+ }
+ ee->func.fn_pre_free = func;
+}
+
+/**
+ * Get an Ecore_Evas's Evas
+ * @param ee The Ecore_Evas whose Evas you wish to get
+ * @return The Evas wrapped by @p ee
+ *
+ * This function returns the Evas contained within @p ee.
+ */
+EAPI Evas *
+ecore_evas_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_get");
+ return NULL;
+ }
+ return ee->evas;
+}
+
+/**
+ * Move an Ecore_Evas
+ * @param ee The Ecore_Evas to move
+ * @param x The x coordinate to move to
+ * @param y The y coordinate to move to
+ *
+ * This moves @p ee to the screen coordinates (@p x, @p y)
+ */
+EAPI void
+ecore_evas_move(Ecore_Evas *ee, int x, int y)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_move");
+ return;
+ }
+ if (ee->prop.fullscreen) return;
+ IFC(ee, fn_move) (ee, x, y);
+ IFE;
+}
+
+/**
+ * Provide Managed move co-ordinates for an Ecore_Evas
+ * @param ee The Ecore_Evas to move
+ * @param x The x coordinate to set as the managed location
+ * @param y The y coordinate to set as the managed location
+ *
+ * This sets the managed geometry position of the @p ee to (@p x, @p y)
+ */
+EAPI void
+ecore_evas_managed_move(Ecore_Evas *ee, int x, int y)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_move");
+ return;
+ }
+ IFC(ee, fn_managed_move) (ee, x, y);
+ IFE;
+}
+
+/**
+ * Resize an Ecore_Evas
+ * @param ee The Ecore_Evas to move
+ * @param w The w coordinate to resize to
+ * @param h The h coordinate to resize to
+ *
+ * This resizes @p ee to @p w x @p h
+ */
+EAPI void
+ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_resize");
+ return;
+ }
+ if (ee->prop.fullscreen) return;
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_resize) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_resize) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Resize an Ecore_Evas
+ * @param ee The Ecore_Evas to move
+ * @param x The x coordinate to move to
+ * @param y The y coordinate to move to
+ * @param w The w coordinate to resize to
+ * @param h The h coordinate to resize to
+ *
+ * This moves @p ee to the screen coordinates (@p x, @p y) and resizes
+ * it to @p w x @p h.
+ *
+ */
+EAPI void
+ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_move_resize");
+ return;
+ }
+ if (ee->prop.fullscreen) return;
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_move_resize) (ee, x, y, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_move_resize) (ee, x, y, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the geometry of an Ecore_Evas
+ * @param ee The Ecore_Evas whose geometry y
+ * @param x A pointer to an int to place the x coordinate in
+ * @param y A pointer to an int to place the y coordinate in
+ * @param w A pointer to an int to place the w size in
+ * @param h A pointer to an int to place the h size in
+ *
+ * This function takes four pointers to (already allocated) ints, and places
+ * the geometry of @p ee in them.
+ *
+ * @code
+ * int x, y, w, h;
+ * ecore_evas_geometry_get(ee, &x, &y, &w, &h);
+ * @endcode
+ *
+ */
+EAPI void
+ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_geometry_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (x) *x = ee->x;
+ if (y) *y = ee->y;
+ if (w) *w = ee->h;
+ if (h) *h = ee->w;
+ }
+ else
+ {
+ if (x) *x = ee->x;
+ if (y) *y = ee->y;
+ if (w) *w = ee->w;
+ if (h) *h = ee->h;
+ }
+}
+
+/**
+ * Set the rotation of an Ecore_Evas' window
+ *
+ * @param ee The Ecore_Evas
+ * @param rot the angle (in degrees) of rotation.
+ *
+ * The allowed values of @p rot depend on the engine being used. Most only
+ * allow multiples of 90.
+ */
+EAPI void
+ecore_evas_rotation_set(Ecore_Evas *ee, int rot)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_rotation_set");
+ return;
+ }
+ rot = rot % 360;
+ while (rot < 0) rot += 360;
+ while (rot >= 360) rot -= 360;
+ IFC(ee, fn_rotation_set) (ee, rot, 0);
+ /* make sure everything gets redrawn */
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ IFE;
+}
+
+/**
+ * Set the rotation of an Ecore_Evas' window
+ *
+ * @param ee The Ecore_Evas
+ * @param rot the angle (in degrees) of rotation.
+ *
+ * The allowed values of @p rot depend on the engine being used. Most only
+ * allow multiples of 90.
+ */
+EAPI void
+ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_rotation_set");
+ return;
+ }
+ rot = rot % 360;
+ while (rot < 0) rot += 360;
+ while (rot >= 360) rot -= 360;
+ IFC(ee, fn_rotation_set) (ee, rot, 1);
+ /* make sure everything gets redrawn */
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ IFE;
+}
+
+/**
+ * Set the rotation of an Ecore_Evas' window
+ *
+ * @param ee The Ecore_Evas
+ * @return the angle (in degrees) of rotation.
+ *
+ */
+EAPI int
+ecore_evas_rotation_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_rotation_get");
+ return 0;
+ }
+ return ee->rotation;
+}
+
+/**
+ * Set whether an Ecore_Evas is shaped or not.
+ * @param ee The Ecore_Evas to shape
+ * @param shaped 1 to shape, 0 to not
+ *
+ * This function allows one to make an Ecore_Evas shaped to the contents of the
+ * evas. If @p shaped is 1, @p ee will be transparent in parts of the evas that
+ * contain no objects. If @p shaped is 0, then @p ee will be rectangular, and
+ * and parts with no data will show random framebuffer artifacting. For
+ * non-shaped Ecore_Evases, it is recommend to cover the entire evas with a
+ * background object.
+ */
+EAPI void
+ecore_evas_shaped_set(Ecore_Evas *ee, int shaped)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_shaped_set");
+ return;
+ }
+ IFC(ee, fn_shaped_set) (ee, shaped);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas is shaped or not.
+ * @param ee The Ecore_Evas to query.
+ * @return 1 if shaped, 0 if not.
+ *
+ * This function returns 1 if @p ee is shaped, and 0 if not.
+ */
+EAPI int
+ecore_evas_shaped_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_shaped_get");
+ return 0;
+ }
+ return ee->shaped ? 1:0;
+}
+
+/**
+ * Set whether an Ecore_Evas has an alpha channel or not.
+ * @param ee The Ecore_Evas to shape
+ * @param alpha 1 to enable the alpha channel, 0 to disable it
+ *
+ * This function allows you to make an Ecore_Evas translucent using an
+ * alpha channel. See ecore_evas_shaped_set() for details. The difference
+ * between a shaped window and a window with an alpha channel is that an
+ * alpha channel supports multiple levels of transpararency, as opposed to
+ * the 1 bit transparency of a shaped window (a pixel is either opaque, or
+ * it's transparent).
+ */
+EAPI void
+ecore_evas_alpha_set(Ecore_Evas *ee, int alpha)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_alpha_set");
+ return;
+ }
+ IFC(ee, fn_alpha_set) (ee, alpha);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas has an alpha channel.
+ * @param ee The Ecore_Evas to query.
+ * @return 1 if ee has an alpha channel, 0 if it does not.
+ *
+ * This function returns 1 if @p ee has an alpha channel, and 0 if
+ * it does not.
+ */
+EAPI int
+ecore_evas_alpha_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_alpha_get");
+ return 0;
+ }
+ return ee->alpha ? 1:0;
+}
+
+/**
+ * Set whether an Ecore_Evas has an transparent window or not.
+ * @param ee The Ecore_Evas to shape
+ * @param transparent 1 to enable the transparent window, 0 to disable it
+ *
+ * This function allows you to make an Ecore_Evas translucent using an
+ * alpha channel. See ecore_evas_shaped_set() for details. The difference
+ * between a shaped window and a window with an alpha channel is that an
+ * alpha channel supports multiple levels of transpararency, as opposed to
+ * the 1 bit transparency of a shaped window (a pixel is either opaque, or
+ * it's transparent).
+ */
+EAPI void
+ecore_evas_transparent_set(Ecore_Evas *ee, int transparent)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_transparent_set");
+ return;
+ }
+ IFC(ee, fn_transparent_set) (ee, transparent);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas has an alpha channel.
+ * @param ee The Ecore_Evas to query.
+ * @return 1 if ee has an alpha channel, 0 if it does not.
+ *
+ * This function returns 1 if @p ee has an alpha channel, and 0 if
+ * it does not.
+ */
+EAPI int
+ecore_evas_transparent_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_transparent_get");
+ return 0;
+ }
+ return ee->transparent ? 1:0;
+}
+
+/**
+ * Show an Ecore_Evas' window
+ * @param ee The Ecore_Evas to show.
+ *
+ * This function makes @p ee visible.
+ */
+EAPI void
+ecore_evas_show(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_show");
+ return;
+ }
+ IFC(ee, fn_show) (ee);
+ IFE;
+}
+
+/**
+ * Hide an Ecore_Evas' window
+ * @param ee The Ecore_Evas to show.
+ *
+ * This function makes @p ee hidden.
+ */
+EAPI void
+ecore_evas_hide(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_hide");
+ return;
+ }
+ IFC(ee, fn_hide) (ee);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is visible or not.
+ * @param ee The Ecore_Evas to query.
+ * @return 1 if visible, 0 if not.
+ *
+ * This function queries @p ee and returns 1 if it is visible, and 0 if not.
+ */
+EAPI int
+ecore_evas_visibility_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_visibility_get");
+ return 0;
+ }
+ return ee->visible ? 1:0;
+}
+
+/**
+ * Raise and Ecore_Evas' window.
+ * @param ee The Ecore_Evas to raise.
+ *
+ * This functions raises the Ecore_Evas to the front.
+ */
+EAPI void
+ecore_evas_raise(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_raise");
+ return;
+ }
+ IFC(ee, fn_raise) (ee);
+ IFE;
+}
+
+/**
+ * Lower an Ecore_Evas' window.
+ * @param ee The Ecore_Evas to raise.
+ *
+ * This functions lowers the Ecore_Evas to the back.
+ */
+EAPI void
+ecore_evas_lower(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_lower");
+ return;
+ }
+ IFC(ee, fn_lower) (ee);
+ IFE;
+}
+
+/**
+ * Activate (set focus to, via the window manager) an Ecore_Evas' window.
+ * @param ee The Ecore_Evas to activate.
+ *
+ * This functions activates the Ecore_Evas.
+ */
+EAPI void
+ecore_evas_activate(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_activate");
+ return;
+ }
+ IFC(ee, fn_activate) (ee);
+ IFE;
+}
+
+/**
+ * Set the title of an Ecore_Evas' window
+ * @param ee The Ecore_Evas whose title you wish to set.
+ * @param t The title
+ *
+ * This function sets the title of @p ee to @p t.
+ */
+EAPI void
+ecore_evas_title_set(Ecore_Evas *ee, const char *t)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_title_set");
+ return;
+ }
+ IFC(ee, fn_title_set) (ee, t);
+ IFE;
+}
+
+/**
+ * Get the title of an Ecore_Evas' window
+ * @param ee The Ecore_Evas whose title you wish to get.
+ * @return The title of @p ee.
+ *
+ * This function returns the title of @p ee.
+ */
+EAPI const char *
+ecore_evas_title_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_title_get");
+ return NULL;
+ }
+ return ee->prop.title;
+}
+
+/**
+ * Set the name and class of an Ecore_Evas' window
+ * @param ee the Ecore_Evas
+ * @param n the name
+ * @param c the class
+ *
+ * This function sets the name of @p ee to @p n, and its class to @p c.
+ */
+EAPI void
+ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_name_class_set");
+ return;
+ }
+ IFC(ee, fn_name_class_set) (ee, n, c);
+ IFE;
+}
+
+/**
+ * Get the name and class of an Ecore_Evas' window
+ * @p ee The Ecore_Evas to query
+ * @p n A pointer to a string to place the name in.
+ * @p c A pointer to a string to place the class in.
+ *
+ * This function gets puts the name of @p ee into @p n, and its class into
+ * @p c.
+ */
+EAPI void
+ecore_evas_name_class_get(const Ecore_Evas *ee, const char **n, const char **c)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_name_class_get");
+ return;
+ }
+ if (n) *n = ee->prop.name;
+ if (c) *c = ee->prop.clas;
+}
+
+/**
+ * Set the min size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w The minimum width
+ * @param h The minimum height
+ *
+ * This function sets the minimum size of @p ee to @p w x @p h.
+ */
+EAPI void
+ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_min_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_min_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_min_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the min size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the min width in.
+ * @param h A pointer to an int to place the min height in.
+ *
+ * This function puts the minimum size of @p ee into @p w and @p h.
+ */
+EAPI void
+ecore_evas_size_min_get(const Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_min_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.min.h;
+ if (h) *h = ee->prop.min.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.min.w;
+ if (h) *h = ee->prop.min.h;
+ }
+}
+
+/**
+ * Set the max size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w The maximum width
+ * @param h The maximum height
+ *
+ * This function sets the maximum size of @p ee to @p w x @p h.
+ */
+EAPI void
+ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_max_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_max_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_max_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the max size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the max width in.
+ * @param h A pointer to an int to place the max height in.
+ *
+ * This function puts the maximum size of @p ee into @p w and @p h.
+ */
+EAPI void
+ecore_evas_size_max_get(const Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_max_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.max.h;
+ if (h) *h = ee->prop.max.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.max.w;
+ if (h) *h = ee->prop.max.h;
+ }
+}
+
+/**
+ * Set the base size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w The base width
+ * @param h The base height
+ *
+ * This function sets the base size of @p ee to @p w x @p h.
+ */
+EAPI void
+ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_base_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_base_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_base_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the base size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the base width in.
+ * @param h A pointer to an int to place the base height in.
+ *
+ * This function puts the base size of @p ee into @p w and @p h.
+ */
+EAPI void
+ecore_evas_size_base_get(const Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_base_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.base.h;
+ if (h) *h = ee->prop.base.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.base.w;
+ if (h) *h = ee->prop.base.h;
+ }
+}
+
+/**
+ * Set the step size of an Ecore_Evas
+ * @param ee The Ecore_Evas to set
+ * @param w The step width
+ * @param h The step height
+ *
+ * This function sets the step size of @p ee to @p w x @p h. This limits the
+ * size of an Ecore_Evas to always being an integer multiple of the step size.
+ */
+EAPI void
+ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_step_set");
+ return;
+ }
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ IFC(ee, fn_size_step_set) (ee, h, w);
+ IFE;
+ }
+ else
+ {
+ IFC(ee, fn_size_step_set) (ee, w, h);
+ IFE;
+ }
+}
+
+/**
+ * Get the step size of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @param w A pointer to an int to place the step width in.
+ * @param h A pointer to an int to place the step height in.
+ *
+ * This function puts the step size of @p ee into @p w and @p h.
+ */
+EAPI void
+ecore_evas_size_step_get(const Ecore_Evas *ee, int *w, int *h)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_size_step_get");
+ return;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ if (w) *w = ee->prop.step.h;
+ if (h) *h = ee->prop.step.w;
+ }
+ else
+ {
+ if (w) *w = ee->prop.step.w;
+ if (h) *h = ee->prop.step.h;
+ }
+}
+
+/**
+ * Set the cursor of an Ecore_Evas
+ * @param ee The Ecore_Evas
+ * @param file The path to an image file for the cursor
+ * @param layer
+ * @param hot_x The x coordinate of the cursor's hot spot
+ * @param hot_y The y coordinate of the cursor's hot spot
+ *
+ * This function makes the mouse cursor over @p ee be the image specified by
+ * @p file. The actual point within the image that the mouse is at is specified
+ * by @p hot_x and @p hot_y, which are coordinates with respect to the top left
+ * corner of the cursor image.
+ */
+EAPI void
+ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y)
+{
+ Evas_Object *obj = NULL;
+
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_cursor_set");
+ return;
+ }
+
+ if (file)
+ {
+ int x, y;
+
+ obj = evas_object_image_add(ee->evas);
+ evas_object_image_file_set(obj, file, NULL);
+ evas_object_image_size_get(obj, &x, &y);
+ evas_object_resize(obj, x, y);
+ evas_object_image_fill_set(obj, 0, 0, x, y);
+ }
+
+ IFC(ee, fn_object_cursor_set) (ee, obj, layer, hot_x, hot_y);
+ IFE;
+}
+
+/**
+ * Set the cursor of an Ecore_Evas
+ * @param ee The Ecore_Evas
+ * @param obj The Evas_Object for the cursor
+ * @param layer
+ * @param hot_x The x coordinate of the cursor's hot spot
+ * @param hot_y The y coordinate of the cursor's hot spot
+ *
+ * This function makes the mouse cursor over @p ee be the image specified by
+ * @p file. The actual point within the image that the mouse is at is specified
+ * by @p hot_x and @p hot_y, which are coordinates with respect to the top left
+ * corner of the cursor image.
+ */
+EAPI void
+ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_cursor_set");
+ return;
+ }
+ IFC(ee, fn_object_cursor_set) (ee, obj, layer, hot_x, hot_y);
+ IFE;
+}
+
+/**
+ * Get information about an Ecore_Evas' cursor
+ * @param ee The Ecore_Evas to set
+ * @param obj A pointer to an Evas_Object to place the cursor Evas_Object.
+ * @param layer A pointer to an int to place the cursor's layer in..
+ * @param hot_x A pointer to an int to place the cursor's hot_x coordinate in.
+ * @param hot_y A pointer to an int to place the cursor's hot_y coordinate in.
+ *
+ * This function queries information about an Ecore_Evas' cursor.
+ */
+EAPI void
+ecore_evas_cursor_get(const Ecore_Evas *ee, Evas_Object **obj, int *layer, int *hot_x, int *hot_y)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_cursor_get");
+ return;
+ }
+ if (obj) *obj = ee->prop.cursor.object;
+ if (layer) *layer = ee->prop.cursor.layer;
+ if (hot_x) *hot_x = ee->prop.cursor.hot.x;
+ if (hot_y) *hot_y = ee->prop.cursor.hot.y;
+}
+
+/**
+ * Set the layer of an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param layer The layer to put @p ee on.
+ *
+ * This function moves @p ee to the layer @p layer.
+ */
+EAPI void
+ecore_evas_layer_set(Ecore_Evas *ee, int layer)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_layer_set");
+ return;
+ }
+ IFC(ee, fn_layer_set) (ee, layer);
+ IFE;
+}
+
+/**
+ * Get the layer of an Ecore_Evas' window
+ * @param ee The Ecore_Evas to set
+ * @return the layer @p ee's window is on.
+ *
+ */
+EAPI int
+ecore_evas_layer_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_layer_get");
+ return 0;
+ }
+ return ee->prop.layer;
+}
+
+/**
+ * Set the focus of an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 for focus, 0 to defocus.
+ *
+ * This function focuses @p ee if @p on is 1, or defocuses @p ee if @p on is 0.
+ */
+EAPI void
+ecore_evas_focus_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_focus_set");
+ return;
+ }
+ IFC(ee, fn_focus_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is focused or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee if focused, 0 if not.
+ *
+ */
+EAPI int
+ecore_evas_focus_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_focus_get");
+ return 0;
+ }
+ return ee->prop.focused ? 1:0;
+}
+
+/**
+ * Iconify or uniconify an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 to iconify, 0 to uniconify.
+ *
+ * This function iconifies @p ee if @p on is 1, or uniconifies @p ee if @p on
+ * is 0.
+ */
+EAPI void
+ecore_evas_iconified_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_iconified_set");
+ return;
+ }
+ IFC(ee, fn_iconified_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is iconified or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is iconified, 0 if not.
+ *
+ */
+EAPI int
+ecore_evas_iconified_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_iconified_get");
+ return 0;
+ }
+ return ee->prop.iconified ? 1:0;
+}
+
+/**
+ * Set whether an Ecore_Evas' window is borderless or not
+ * @param ee The Ecore_Evas
+ * @param on 1 for borderless, 0 for bordered.
+ *
+ * This function makes @p ee borderless if @p on is 1, or bordered if @p on
+ * is 0.
+ */
+EAPI void
+ecore_evas_borderless_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_borderless_set");
+ return;
+ }
+ IFC(ee, fn_borderless_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is borderless or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is borderless, 0 if not.
+ *
+ */
+EAPI int
+ecore_evas_borderless_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_borderless_get");
+ return 0;
+ }
+ return ee->prop.borderless ? 1:0;
+}
+
+/**
+ * Tell the WM whether or not to ignore an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 to ignore, 0 to not.
+ *
+ * This function causes the window manager to ignore @p ee if @p on is 1,
+ * or not ignore @p ee if @p on is 0.
+ */
+EAPI void
+ecore_evas_override_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_override_set");
+ return;
+ }
+ IFC(ee, fn_override_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is overridden or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is overridden, 0 if not.
+ *
+ */
+EAPI int
+ecore_evas_override_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_override_get");
+ return 0;
+ }
+ return ee->prop.override ? 1:0;
+}
+
+/**
+ * Maximize (or unmaximize) an Ecore_Evas' window
+ * @param ee The Ecore_Evas
+ * @param on 1 to maximize, 0 to unmaximize.
+ *
+ * This function maximizes @p ee if @p on is 1, or unmaximizes @p ee
+ * if @p on is 0.
+ */
+EAPI void
+ecore_evas_maximized_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_maximized_set");
+ return;
+ }
+ IFC(ee, fn_maximized_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is maximized or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is maximized, 0 if not.
+ *
+ */
+EAPI int
+ecore_evas_maximized_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_maximized_get");
+ return 0;
+ }
+ return ee->prop.maximized ? 1:0;
+}
+
+/**
+ * Set whether or not an Ecore_Evas' window is fullscreen
+ * @param ee The Ecore_Evas
+ * @param on 1 fullscreen, 0 not.
+ *
+ * This function causes @p ee to be fullscreen if @p on is 1,
+ * or not if @p on is 0.
+ */
+EAPI void
+ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_fullscreen_set");
+ return;
+ }
+ IFC(ee, fn_fullscreen_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window is fullscreen or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee is fullscreen, 0 if not.
+ *
+ */
+EAPI int
+ecore_evas_fullscreen_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_fullscreen_get");
+ return 0;
+ }
+ return ee->prop.fullscreen ? 1:0;
+}
+
+/**
+ * Set whether or not an Ecore_Evas' window should avoid damage
+ *
+ * @param ee The Ecore_Evas
+ * @param on 1 to avoid damage, 0 to not
+ *
+ * This function causes @p ee to be drawn to a pixmap to avoid recalculations.
+ * On expose events it will copy from the pixmap to the window.
+ */
+EAPI void
+ecore_evas_avoid_damage_set(Ecore_Evas *ee, Ecore_Evas_Avoid_Damage_Type on)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_avoid_damage_set");
+ return;
+ }
+ IFC(ee, fn_avoid_damage_set) (ee, on);
+ IFE;
+}
+
+/**
+ * Query whether an Ecore_Evas' window avoids damage or not
+ * @param ee The Ecore_Evas to set
+ * @return 1 if @p ee avoids damage, 0 if not.
+ *
+ */
+EAPI Ecore_Evas_Avoid_Damage_Type
+ecore_evas_avoid_damage_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_avoid_damage_get");
+ return 0;
+ }
+ return ee->prop.avoid_damage;
+}
+
+/**
+ * Set the withdrawn state of an Ecore_Evas' window.
+ * @param ee The Ecore_Evas whose window's withdrawn state is set.
+ * @param withdrawn The Ecore_Evas window's new withdrawn state.
+ *
+ */
+EAPI void
+ecore_evas_withdrawn_set(Ecore_Evas *ee, int withdrawn)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_withdrawn_set");
+ return;
+ }
+
+ IFC(ee, fn_withdrawn_set) (ee, withdrawn);
+ IFE;
+}
+
+/**
+ * Returns the withdrawn state of an Ecore_Evas' window.
+ * @param ee The Ecore_Evas whose window's withdrawn state is returned.
+ * @return The Ecore_Evas window's withdrawn state.
+ *
+ */
+EAPI int
+ecore_evas_withdrawn_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_withdrawn_get");
+ return 0;
+ } else
+ return ee->prop.withdrawn ? 1:0;
+}
+
+/**
+ * Set the sticky state of an Ecore_Evas window.
+ *
+ * @param ee The Ecore_Evas whose window's sticky state is set.
+ * @param sticky The Ecore_Evas window's new sticky state.
+ *
+ */
+EAPI void
+ecore_evas_sticky_set(Ecore_Evas *ee, int sticky)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_sticky_set");
+ return;
+ }
+
+ IFC(ee, fn_sticky_set) (ee, sticky);
+ IFE;
+}
+
+/**
+ * Returns the sticky state of an Ecore_Evas' window.
+ *
+ * @param ee The Ecore_Evas whose window's sticky state is returned.
+ * @return The Ecore_Evas window's sticky state.
+ *
+ */
+EAPI int
+ecore_evas_sticky_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_sticky_get");
+ return 0;
+ } else
+ return ee->prop.sticky ? 1:0;
+}
+
+/**
+ * Set if this evas should ignore events
+ *
+ * @param ee The Ecore_Evas whose window's to ignore events.
+ * @param ignore The Ecore_Evas new ignore state.
+ *
+ */
+EAPI void
+ecore_evas_ignore_events_set(Ecore_Evas *ee, int ignore)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_ignore_events_set");
+ return;
+ }
+
+ IFC(ee, fn_ignore_events_set) (ee, ignore);
+ IFE;
+}
+
+/**
+ * Returns the ignore state of an Ecore_Evas' window.
+ *
+ * @param ee The Ecore_Evas whose window's ignore events state is returned.
+ * @return The Ecore_Evas window's ignore state.
+ *
+ */
+EAPI int
+ecore_evas_ignore_events_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_ignore_events_get");
+ return 0;
+ }
+ return ee->ignore_events ? 1 : 0;
+}
+
+EAPI void
+ecore_evas_manual_render_set(Ecore_Evas *ee, int manual_render)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_manual_render_set");
+ return;
+ }
+ ee->manual_render = manual_render;
+}
+
+EAPI int
+ecore_evas_manual_render_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_manual_render_get");
+ return 0;
+ }
+ return ee->manual_render ? 1 : 0;
+}
+
+EAPI void
+ecore_evas_manual_render(Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_manual_render");
+ return;
+ }
+ if (ee->engine.func->fn_render)
+ ee->engine.func->fn_render(ee);
+}
+
+EAPI void
+ecore_evas_comp_sync_set(Ecore_Evas *ee, int do_sync)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_comp_sync_set");
+ return;
+ }
+ ee->no_comp_sync = !do_sync;
+}
+
+EAPI int
+ecore_evas_comp_sync_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_comp_sync_get");
+ return 0;
+ }
+ return !ee->no_comp_sync;
+}
+
+EAPI Ecore_Window
+ecore_evas_window_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+ "ecore_evas_window_get");
+ return 0;
+ }
+
+ return ee->prop.window;
+}
+
+/* fps debug calls - for debugging how much time your app actually spends */
+/* rendering graphics... :) */
+
+static int _ecore_evas_fps_debug_init_count = 0;
+static int _ecore_evas_fps_debug_fd = -1;
+unsigned int *_ecore_evas_fps_rendertime_mmap = NULL;
+
+void
+_ecore_evas_fps_debug_init(void)
+{
+ char buf[4096];
+
+ _ecore_evas_fps_debug_init_count++;
+ if (_ecore_evas_fps_debug_init_count > 1) return;
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_evas_fps_debug-%i", (int)getpid());
+ _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
+ if (_ecore_evas_fps_debug_fd < 0)
+ {
+ unlink(buf);
+ _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
+ }
+ if (_ecore_evas_fps_debug_fd >= 0)
+ {
+ unsigned int zero = 0;
+ char *buf = (char *)&zero;
+ ssize_t todo = sizeof(unsigned int);
+
+ while (todo > 0)
+ {
+ ssize_t r = write(_ecore_evas_fps_debug_fd, buf, todo);
+ if (r > 0)
+ {
+ todo -= r;
+ buf += r;
+ }
+ else if ((r < 0) && (errno == EINTR))
+ continue;
+ else
+ {
+ ERR("could not write to file '%s' fd %d: %s",
+ buf, _ecore_evas_fps_debug_fd, strerror(errno));
+ close(_ecore_evas_fps_debug_fd);
+ _ecore_evas_fps_debug_fd = -1;
+ return;
+ }
+ }
+ _ecore_evas_fps_rendertime_mmap = mmap(NULL, sizeof(unsigned int),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ _ecore_evas_fps_debug_fd, 0);
+ if (_ecore_evas_fps_rendertime_mmap == MAP_FAILED)
+ _ecore_evas_fps_rendertime_mmap = NULL;
+ }
+}
+
+void
+_ecore_evas_fps_debug_shutdown(void)
+{
+ _ecore_evas_fps_debug_init_count--;
+ if (_ecore_evas_fps_debug_init_count > 0) return;
+ if (_ecore_evas_fps_debug_fd >= 0)
+ {
+ char buf[4096];
+
+ snprintf(buf, sizeof(buf), "/tmp/.ecore_evas_fps_debug-%i", (int)getpid());
+ unlink(buf);
+ if (_ecore_evas_fps_rendertime_mmap)
+ {
+ munmap(_ecore_evas_fps_rendertime_mmap, sizeof(int));
+ _ecore_evas_fps_rendertime_mmap = NULL;
+ }
+ close(_ecore_evas_fps_debug_fd);
+ _ecore_evas_fps_debug_fd = -1;
+ }
+}
+
+void
+_ecore_evas_fps_debug_rendertime_add(double t)
+{
+ static double rtime = 0.0;
+ static double rlapse = 0.0;
+ static int frames = 0;
+ static int flapse = 0;
+ double tim;
+
+ tim = ecore_time_get();
+ rtime += t;
+ frames++;
+ if (rlapse == 0.0)
+ {
+ rlapse = tim;
+ flapse = frames;
+ }
+ else if ((tim - rlapse) >= 0.5)
+ {
+ printf("FRAME: %i, FPS: %3.1f, RTIME %3.0f%%\n",
+ frames,
+ (frames - flapse) / (tim - rlapse),
+ (100.0 * rtime) / (tim - rlapse)
+ );
+ rlapse = tim;
+ flapse = frames;
+ rtime = 0.0;
+ }
+}
+
+void
+_ecore_evas_register(Ecore_Evas *ee)
+{
+ ee->registered = 1;
+ ecore_evases = (Ecore_Evas *)eina_inlist_prepend
+ (EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
+}
+
+void
+_ecore_evas_free(Ecore_Evas *ee)
+{
+ if (ee->func.fn_pre_free) ee->func.fn_pre_free(ee);
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE);
+ while (ee->sub_ecore_evas)
+ {
+ _ecore_evas_free(ee->sub_ecore_evas->data);
+ }
+ if (ee->data) eina_hash_free(ee->data);
+ if (ee->name) free(ee->name);
+ if (ee->prop.title) free(ee->prop.title);
+ if (ee->prop.name) free(ee->prop.name);
+ if (ee->prop.clas) free(ee->prop.clas);
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+ if (ee->evas) evas_free(ee->evas);
+ ee->data = NULL;
+ ee->driver = NULL;
+ ee->name = NULL;
+ ee->prop.title = NULL;
+ ee->prop.name = NULL;
+ ee->prop.clas = NULL;
+ ee->prop.cursor.object = NULL;
+ ee->evas = NULL;
+ if (ee->engine.idle_flush_timer)
+ ecore_timer_del(ee->engine.idle_flush_timer);
+ if (ee->engine.func->fn_free) ee->engine.func->fn_free(ee);
+ if (ee->registered)
+ {
+ ecore_evases = (Ecore_Evas *)eina_inlist_remove
+ (EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
+ }
+ free(ee);
+}
+
+static int
+_ecore_evas_cb_idle_flush(void *data)
+{
+ Ecore_Evas *ee;
+
+ ee = (Ecore_Evas *)data;
+ evas_render_idle_flush(ee->evas);
+ ee->engine.idle_flush_timer = NULL;
+ return 0;
+}
+
+static int
+_ecore_evas_async_events_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ evas_async_events_process();
+
+ return 1;
+}
+
+void
+_ecore_evas_idle_timeout_update(Ecore_Evas *ee)
+{
+ if (ee->engine.idle_flush_timer)
+ ecore_timer_del(ee->engine.idle_flush_timer);
+ ee->engine.idle_flush_timer = ecore_timer_add(IDLE_FLUSH_TIME,
+ _ecore_evas_cb_idle_flush,
+ ee);
+}
+
+void
+_ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
+{
+ ee->mouse.x = x;
+ ee->mouse.y = y;
+ if (ee->prop.cursor.object)
+ {
+ evas_object_show(ee->prop.cursor.object);
+ if (ee->rotation == 0)
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 90)
+ evas_object_move(ee->prop.cursor.object,
+ ee->h - y - 1 - ee->prop.cursor.hot.x,
+ x - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 180)
+ evas_object_move(ee->prop.cursor.object,
+ ee->w - x - 1 - ee->prop.cursor.hot.x,
+ ee->h - y - 1 - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 270)
+ evas_object_move(ee->prop.cursor.object,
+ y - ee->prop.cursor.hot.x,
+ ee->w - x - 1 - ee->prop.cursor.hot.y);
+ }
+ if (ee->rotation == 0)
+ evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
+ else if (ee->rotation == 90)
+ evas_event_feed_mouse_move(ee->evas, ee->h - y - 1, x, timestamp, NULL);
+ else if (ee->rotation == 180)
+ evas_event_feed_mouse_move(ee->evas, ee->w - x - 1, ee->h - y - 1, timestamp, NULL);
+ else if (ee->rotation == 270)
+ evas_event_feed_mouse_move(ee->evas, y, ee->w - x - 1, timestamp, NULL);
+}
+
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include "ecore_private.h"
+#include <Ecore_Input.h>
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+static int _ecore_evas_init_count = 0;
+
+static int
+_ecore_evas_buffer_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_buffer_free(Ecore_Evas *ee)
+{
+ if (ee->engine.buffer.image)
+ {
+ Ecore_Evas *ee2;
+
+ ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent");
+ evas_object_del(ee->engine.buffer.image);
+ ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee);
+ }
+ else
+ {
+ free(ee->engine.buffer.pixels);
+ }
+ _ecore_evas_buffer_shutdown();
+}
+
+static void
+_ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ Evas_Engine_Info_Buffer *einfo;
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ if (ee->engine.buffer.image)
+ {
+ ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1);
+ }
+ else
+ {
+ if (ee->engine.buffer.pixels) free(ee->engine.buffer.pixels);
+ ee->engine.buffer.pixels = malloc(ee->w * ee->h * sizeof(int));
+ }
+
+ einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+ einfo->info.dest_buffer = ee->engine.buffer.pixels;
+ einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int);
+ einfo->info.use_color_key = 0;
+ einfo->info.alpha_threshold = 0;
+ einfo->info.func.new_update_region = NULL;
+ einfo->info.func.free_update_region = NULL;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+int
+_ecore_evas_buffer_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+int
+_ecore_evas_buffer_render(Ecore_Evas *ee)
+{
+ Eina_List *updates, *l, *ll;
+ Ecore_Evas *ee2;
+ int rend = 0;
+
+ EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+ {
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ rend |= _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+ if (ee->engine.buffer.image)
+ {
+ int w, h;
+
+ evas_object_image_size_get(ee->engine.buffer.image, &w, &h);
+ if ((w != ee->w) || (h != ee->h))
+ _ecore_evas_resize(ee, w, h);
+ }
+ updates = evas_render_updates(ee->evas);
+ if (ee->engine.buffer.image)
+ {
+ Eina_Rectangle *r;
+
+ EINA_LIST_FOREACH(updates, l, r)
+ if (ee->engine.buffer.image)
+ evas_object_image_data_update_add(ee->engine.buffer.image,
+ r->x, r->y, r->w, r->h);
+ }
+ if (updates)
+ {
+ evas_render_updates_free(updates);
+ _ecore_evas_idle_timeout_update(ee);
+ }
+
+ return updates ? 1 : rend;
+}
+
+static void
+_ecore_evas_buffer_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
+{
+ Evas_Coord xx, yy, fx, fy, fw, fh;
+
+ evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, NULL, NULL);
+ evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh);
+
+ if (fw < 1) fw = 1;
+ xx = (*x - xx) - fx;
+ while (xx < 0) xx += fw;
+ while (xx > fw) xx -= fw;
+ *x = (ee->w * xx) / fw;
+
+ if (fh < 1) fh = 1;
+ yy = (*y - yy) - fy;
+ while (yy < 0) yy += fh;
+ while (yy > fh) yy -= fh;
+ *y = (ee->h * yy) / fh;
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_In *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Out *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Down *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_down(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Up *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_up(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Move *ev;
+ Evas_Coord x, y;
+
+ ee = data;
+ ev = event_info;
+ x = ev->cur.canvas.x;
+ y = ev->cur.canvas.y;
+ _ecore_evas_buffer_coord_translate(ee, &x, &y);
+ _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp);
+}
+
+static void
+_ecore_evas_buffer_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Mouse_Wheel *ev;
+
+ ee = data;
+ ev = event_info;
+ evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_multi_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Multi_Down *ev;
+ Evas_Coord x, y, xx, yy;
+ double xf, yf;
+
+ ee = data;
+ ev = event_info;
+ x = ev->canvas.x;
+ y = ev->canvas.y;
+ xx = x;
+ yy = y;
+ _ecore_evas_buffer_coord_translate(ee, &x, &y);
+ xf = (ev->canvas.xsub - (double)xx) + (double)x;
+ yf = (ev->canvas.ysub - (double)yy) + (double)y;
+ evas_event_feed_multi_down(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_multi_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Multi_Up *ev;
+ Evas_Coord x, y, xx, yy;
+ double xf, yf;
+
+ ee = data;
+ ev = event_info;
+ x = ev->canvas.x;
+ y = ev->canvas.y;
+ xx = x;
+ yy = y;
+ _ecore_evas_buffer_coord_translate(ee, &x, &y);
+ xf = (ev->canvas.xsub - (double)xx) + (double)x;
+ yf = (ev->canvas.ysub - (double)yy) + (double)y;
+ evas_event_feed_multi_up(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Multi_Move *ev;
+ Evas_Coord x, y, xx, yy;
+ double xf, yf;
+
+ ee = data;
+ ev = event_info;
+ x = ev->cur.canvas.x;
+ y = ev->cur.canvas.y;
+ xx = x;
+ yy = y;
+ _ecore_evas_buffer_coord_translate(ee, &x, &y);
+ xf = (ev->cur.canvas.xsub - (double)xx) + (double)x;
+ yf = (ev->cur.canvas.ysub - (double)yy) + (double)y;
+ evas_event_feed_multi_move(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ if (ee->driver) _ecore_evas_free(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_key_down(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Key_Down *ev;
+
+ ee = data;
+ ev = event_info;
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift"))
+ evas_key_modifier_on(e, "Shift");
+ else
+ evas_key_modifier_off(e, "Shift");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control"))
+ evas_key_modifier_on(e, "Control");
+ else
+ evas_key_modifier_off(e, "Control");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt"))
+ evas_key_modifier_on(e, "Alt");
+ else
+ evas_key_modifier_off(e, "Alt");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta"))
+ evas_key_modifier_on(e, "Meta");
+ else
+ evas_key_modifier_off(e, "Meta");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper"))
+ evas_key_modifier_on(e, "Hyper");
+ else
+ evas_key_modifier_off(e, "Hyper");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super"))
+ evas_key_modifier_on(e, "Super");
+ else
+ evas_key_modifier_off(e, "Super");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock"))
+ evas_key_lock_on(e, "Scroll_Lock");
+ else
+ evas_key_lock_off(e, "Scroll_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock"))
+ evas_key_lock_on(e, "Num_Lock");
+ else
+ evas_key_lock_off(e, "Num_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock"))
+ evas_key_lock_on(e, "Caps_Lock");
+ else
+ evas_key_lock_off(e, "Caps_Lock");
+ evas_event_feed_key_down(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_key_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Ecore_Evas *ee;
+ Evas_Event_Key_Up *ev;
+
+ ee = data;
+ ev = event_info;
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift"))
+ evas_key_modifier_on(e, "Shift");
+ else
+ evas_key_modifier_off(e, "Shift");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control"))
+ evas_key_modifier_on(e, "Control");
+ else
+ evas_key_modifier_off(e, "Control");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt"))
+ evas_key_modifier_on(e, "Alt");
+ else
+ evas_key_modifier_off(e, "Alt");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta"))
+ evas_key_modifier_on(e, "Meta");
+ else
+ evas_key_modifier_off(e, "Meta");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper"))
+ evas_key_modifier_on(e, "Hyper");
+ else
+ evas_key_modifier_off(e, "Hyper");
+ if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super"))
+ evas_key_modifier_on(e, "Super");
+ else
+ evas_key_modifier_off(e, "Super");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock"))
+ evas_key_lock_on(e, "Scroll_Lock");
+ else
+ evas_key_lock_off(e, "Scroll_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock"))
+ evas_key_lock_on(e, "Num_Lock");
+ else
+ evas_key_lock_off(e, "Num_Lock");
+ if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock"))
+ evas_key_lock_on(e, "Caps_Lock");
+ else
+ evas_key_lock_off(e, "Caps_Lock");
+ evas_event_feed_key_up(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_buffer_cb_focus_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->prop.focused = 1;
+ evas_focus_in(ee->evas);
+ if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_focus_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->prop.focused = 0;
+ evas_focus_out(ee->evas);
+ if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->visible = 1;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+}
+
+static void
+_ecore_evas_buffer_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ ee->visible = 0;
+ if (ee->func.fn_hide) ee->func.fn_hide(ee);
+}
+
+static Ecore_Evas_Engine_Func _ecore_buffer_engine_func =
+{
+ _ecore_evas_buffer_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_resize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, //transparent
+
+ NULL // render
+};
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI Ecore_Evas *
+ecore_evas_buffer_new(int w, int h)
+{
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ Evas_Engine_Info_Buffer *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("buffer");
+ if (!rmethod) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_buffer_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func;
+
+ ee->driver = "buffer";
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->rotation = 0;
+ ee->visible = 1;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 1;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 1;
+ ee->prop.fullscreen = 0;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.buffer.pixels = malloc(w * h * sizeof(int));
+
+ einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+ einfo->info.dest_buffer = ee->engine.buffer.pixels;
+ einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int);
+ einfo->info.use_color_key = 0;
+ einfo->info.alpha_threshold = 0;
+ einfo->info.func.new_update_region = NULL;
+ einfo->info.func.free_update_region = NULL;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ evas_event_feed_mouse_in(ee->evas, 0, NULL);
+
+ ee->engine.func->fn_render = _ecore_evas_buffer_render;
+ _ecore_evas_register(ee);
+
+ return ee;
+#else
+ return NULL;
+#endif
+}
+
+EAPI const void *
+ecore_evas_buffer_pixels_get(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ _ecore_evas_buffer_render(ee);
+ return ee->engine.buffer.pixels;
+#else
+ return NULL;
+#endif
+}
+
+EAPI Evas_Object *
+ecore_evas_object_image_new(Ecore_Evas *ee_target)
+{
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ Evas_Object *o;
+ Evas_Engine_Info_Buffer *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+ int w, h;
+
+ rmethod = evas_render_method_lookup("buffer");
+ if (!rmethod) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ o = evas_object_image_add(ee_target->evas);
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_buffer_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func;
+
+ ee->driver = "buffer";
+
+ w = 1;
+ h = 1;
+ ee->rotation = 0;
+ ee->visible = 0;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 0;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 0;
+ ee->prop.fullscreen = 0;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.buffer.image = o;
+ evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas", ee);
+ evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas_Parent", ee_target);
+ evas_object_image_size_set(o, ee->w, ee->h);
+ evas_object_image_alpha_set(o, 1);
+ ee->engine.buffer.pixels = evas_object_image_data_get(o, 1);
+ evas_object_image_data_set(o, ee->engine.buffer.pixels);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_IN,
+ _ecore_evas_buffer_cb_mouse_in, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_OUT,
+ _ecore_evas_buffer_cb_mouse_out, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_DOWN,
+ _ecore_evas_buffer_cb_mouse_down, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_UP,
+ _ecore_evas_buffer_cb_mouse_up, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_MOVE,
+ _ecore_evas_buffer_cb_mouse_move, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MOUSE_WHEEL,
+ _ecore_evas_buffer_cb_mouse_wheel, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MULTI_DOWN,
+ _ecore_evas_buffer_cb_multi_down, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MULTI_UP,
+ _ecore_evas_buffer_cb_multi_up, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_MULTI_MOVE,
+ _ecore_evas_buffer_cb_multi_move, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_FREE,
+ _ecore_evas_buffer_cb_free, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_KEY_DOWN,
+ _ecore_evas_buffer_cb_key_down, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_KEY_UP,
+ _ecore_evas_buffer_cb_key_up, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_FOCUS_IN,
+ _ecore_evas_buffer_cb_focus_in, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_FOCUS_OUT,
+ _ecore_evas_buffer_cb_focus_out, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_SHOW,
+ _ecore_evas_buffer_cb_show, ee);
+ evas_object_event_callback_add(ee->engine.buffer.image,
+ EVAS_CALLBACK_HIDE,
+ _ecore_evas_buffer_cb_hide, ee);
+ einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+ einfo->info.dest_buffer = ee->engine.buffer.pixels;
+ einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int);
+ einfo->info.use_color_key = 0;
+ einfo->info.alpha_threshold = 0;
+ einfo->info.func.new_update_region = NULL;
+ einfo->info.func.free_update_region = NULL;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee);
+
+ ee->engine.func->fn_render = _ecore_evas_buffer_render;
+
+ return o;
+#else
+ return NULL;
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef BUILD_ECORE_EVAS_COCOA
+#import <Cocoa/Cocoa.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Input.h"
+#include "Ecore_Input_Evas.h"
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_COCOA
+#include "Ecore_Cocoa.h"
+#include "Evas_Engine_Quartz.h"
+
+// FIXME: this engine has lots of problems. only 1 window at a time, drawRect looks wrong, doesnt handle resizes and more
+
+static int _ecore_evas_init_count = 0;
+static Ecore_Evas *ecore_evases = NULL;
+static Ecore_Event_Handler *ecore_evas_event_handlers[4] = {
+ NULL, NULL, NULL, NULL
+};
+static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL;
+static Ecore_Poller *ecore_evas_event = NULL;
+
+static const char *ecore_evas_cocoa_default = "EFL Cocoa";
+
+@interface EvasView : NSView
+{
+ CGContextRef ctx;
+}
+@end
+
+static EvasView * evas_view;
+static NSWindow * main_window;
+
+@implementation EvasView
+
+- (id) init
+{
+ self = [super init];
+ if (self != nil)
+ {
+ ctx = NULL;
+ }
+ return self;
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ if(ctx != NULL)
+ {
+ Ecore_Evas *ee;
+
+ EINA_INLIST_FOREACH(ecore_evases, ee)
+ {
+ if (ee->visible)
+ evas_damage_rectangle_add(ee->evas, 0, 0, 400, 400);
+ }
+ return;
+ }
+
+ ctx = [[NSGraphicsContext currentContext] graphicsPort];
+ CGContextRetain(ctx);
+}
+
+- (CGContextRef)context
+{
+ return ctx;
+}
+
+@end
+
+static Ecore_Evas *
+_ecore_evas_cocoa_match(void)
+{
+ return ecore_evases;
+}
+
+static int
+_ecore_evas_cocoa_event_got_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+
+ ee = _ecore_evas_cocoa_match();
+
+ if (!ee) return 1;
+ ee->prop.focused = 1;
+
+ return 0;
+}
+
+static int
+_ecore_evas_cocoa_event_lost_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+
+ ee = _ecore_evas_cocoa_match();
+
+ if (!ee) return 1;
+ ee->prop.focused = 0;
+
+ return 0;
+}
+
+static int
+_ecore_evas_cocoa_event_video_resize(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ /*Ecore_Cocoa_Event_Video_Resize *e;
+ Ecore_Evas *ee;
+
+ e = event;
+ ee = _ecore_evas_cocoa_match();
+
+ if (!ee) return 1; // pass on event
+ evas_output_size_set(ee->evas, e->w, e->h);
+
+ return 0;*/
+}
+
+static int
+_ecore_evas_cocoa_event_video_expose(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+{
+ Ecore_Evas *ee;
+ int w;
+ int h;
+
+ ee = _ecore_evas_cocoa_match();
+
+ if (!ee) return 1;
+ evas_output_size_get(ee->evas, &w, &h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, w, h);
+
+ return 0;
+}
+
+static int
+_ecore_evas_idle_enter(void *data __UNUSED__)
+{
+ Ecore_Evas *ee;
+ double t1 = 0.;
+ double t2 = 0.;
+
+ EINA_INLIST_FOREACH(ecore_evases, ee)
+ {
+ if (ee->visible)
+ evas_render(ee->evas);
+ else
+ evas_norender(ee->evas);
+ }
+
+ return 1;
+}
+
+static int
+_ecore_evas_cocoa_event(void *data)
+{
+ ecore_cocoa_feed_events();
+
+ return 1;
+}
+
+static int
+_ecore_evas_cocoa_init(int w, int h)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+
+ ecore_event_evas_init();
+
+ ecore_evas_idle_enterer = ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
+ ecore_evas_event = ecore_poller_add(ECORE_POLLER_CORE, 1, ecore_evas_event, NULL);
+ ecore_poller_poll_interval_set(ECORE_POLLER_CORE, 0.006);
+
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_COCOA_EVENT_GOT_FOCUS, _ecore_evas_cocoa_event_got_focus, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_COCOA_EVENT_LOST_FOCUS, _ecore_evas_cocoa_event_lost_focus, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_COCOA_EVENT_RESIZE, _ecore_evas_cocoa_event_video_resize, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_COCOA_EVENT_EXPOSE, _ecore_evas_cocoa_event_video_expose, NULL);
+
+ return _ecore_evas_init_count;
+}
+
+static int
+_ecore_evas_cocoa_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ while (ecore_evases) _ecore_evas_free(ecore_evases);
+
+ for (i = 0; i < sizeof (ecore_evas_event_handlers) / sizeof (Ecore_Event_Handler*); i++)
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ ecore_event_evas_shutdown();
+ ecore_idle_enterer_del(ecore_evas_idle_enterer);
+ ecore_evas_idle_enterer = NULL;
+ ecore_poller_del(ecore_evas_event);
+ ecore_evas_event = NULL;
+
+ ecore_event_evas_shutdown();
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_cocoa_free(Ecore_Evas *ee)
+{
+ ecore_evases = (Ecore_Evas *) eina_inlist_remove(EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
+ ecore_event_window_unregister(0);
+ _ecore_evas_cocoa_shutdown();
+ ecore_cocoa_shutdown();
+}
+
+static void
+_ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_object_cursor_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ if (ee)
+ ee->prop.cursor.object = NULL;
+}
+
+static void
+_ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+ int x, y;
+
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+ if (obj == NULL)
+ {
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ return;
+ }
+
+ ee->prop.cursor.object = obj;
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
+}
+
+static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
+{
+ _ecore_evas_cocoa_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_resize,
+ _ecore_evas_move_resize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_object_cursor_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, //transparent
+
+ NULL // render
+};
+#endif
+
+EAPI Ecore_Evas *
+ecore_evas_cocoa_new(const char* name, int w, int h)
+{
+#ifdef BUILD_ECORE_EVAS_COCOA
+ Evas_Engine_Info_Quartz *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ if (!name)
+ name = ecore_evas_cocoa_default;
+
+ rmethod = evas_render_method_lookup("quartz");
+ if (!rmethod) return NULL;
+
+ if (!ecore_cocoa_init(name)) return NULL;
+
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee)
+ goto shutdown_ecore_cocoa;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_cocoa_init(w, h);
+
+ ecore_event_window_register(0, ee, ee->evas, _ecore_evas_mouse_move_process);
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_cocoa_engine_func;
+
+ ee->driver = "quartz";
+ if (name) ee->name = strdup(name);
+ if (!ee->name)
+ goto free_ee;
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->visible = 1;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 1;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 1;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+
+ // init evas here
+ ee->evas = evas_new();
+ if (!ee->evas)
+ goto free_name;
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+
+ // Set up the Cocoa runtime
+ [[NSAutoreleasePool alloc] init];
+ [NSApplication sharedApplication];
+
+ // Register ourselves as a full-fledged Cocoa app, instead of a NSUIElement.
+ // This gives benefits like window focus and a dock icon!
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ TransformProcessType (&psn, kProcessTransformToForegroundApplication);
+
+ [NSApp finishLaunching];
+
+ // Create our main window, and embed an EvasView in it
+ main_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,w,h) styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask) backing:NSBackingStoreBuffered defer:NO screen:nil];
+ /* FIXME: manage the case where main_window is NULL witht a goto free_evas; */
+ [main_window makeKeyAndOrderFront:NSApp];
+ [main_window setTitle:[NSString stringWithUTF8String:name]];
+ [main_window makeMainWindow];
+ [main_window setAcceptsMouseMovedEvents:YES];
+ [NSApp activateIgnoringOtherApps:YES];
+
+ evas_view = [[EvasView alloc] initWithFrame:NSMakeRect(0,0,w,h)];
+ [[main_window contentView] addSubview:evas_view];
+
+ // drawRect: must be run at least once, to make sure we've set ctx
+ [evas_view display];
+
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ einfo = (Evas_Engine_Info_Quartz*) evas_engine_info_get(ee->evas);
+ if (!einfo)
+ goto free_window;
+
+ einfo->info.context = [[evas_view context] retain];
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+
+ ecore_evases = (Ecore_Evas *) eina_inlist_prepend(EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
+
+ evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ evas_focus_in(ee->evas);
+
+ return ee;
+
+ free_window:
+ /* FIXME: free window here */
+ free_evas:
+ free(ee->evas);
+ free_name:
+ free(ee->name);
+ free_ee:
+ _ecore_evas_cocoa_shutdown();
+ free(ee);
+ shutdown_ecore_cocoa:
+ ecore_cocoa_shutdown();
+
+ return NULL;
+#else
+ ERR("OUTCH name='%s' size=%dx%d!", name ? name : "", w, h);
+ return NULL;
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <Ecore.h>
+#include "ecore_private.h"
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+#include <Ecore_DirectFB.h>
+#endif
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+static int _ecore_evas_init_count = 0;
+static Ecore_Event_Handler *ecore_evas_event_handlers[13];
+
+static Eina_Hash *ecore_evases_hash = NULL;
+
+static int
+_ecore_evas_directfb_render(Ecore_Evas *ee)
+{
+ Eina_List *updates, *ll;
+ Ecore_Evas *ee2;
+ int rend = 0;
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+ {
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ rend |= _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+ updates = evas_render_updates(ee->evas);
+ if (updates)
+ {
+ evas_render_updates_free(updates);
+ _ecore_evas_idle_timeout_update(ee);
+ }
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+
+ return updates ? 1 : rend;
+}
+
+static char *
+_ecore_evas_directfb_winid_str_get(Ecore_X_Window win)
+{
+ const char *vals = "qWeRtYuIoP5$&<~";
+ static char id[9];
+ unsigned int val;
+ val = (unsigned int)win;
+ id[0] = vals[(val >> 28) & 0xf];
+ id[1] = vals[(val >> 24) & 0xf];
+ id[2] = vals[(val >> 20) & 0xf];
+ id[3] = vals[(val >> 16) & 0xf];
+ id[4] = vals[(val >> 12) & 0xf];
+ id[5] = vals[(val >> 8) & 0xf];
+ id[6] = vals[(val >> 4) & 0xf];
+ id[7] = vals[(val ) & 0xf];
+ id[8] = 0;
+ return id;
+}
+
+static Ecore_Evas *
+_ecore_evas_directfb_match(DFBWindowID win)
+{
+ Ecore_Evas *ee;
+
+ ee = eina_hash_find(ecore_evases_hash, _ecore_evas_directfb_winid_str_get(win));
+ return ee;
+}
+
+static int
+_ecore_evas_directfb_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Key_Down *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_key_down(ee->evas, e->name, e->name, e->string,
+ e->key_compose, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Key_Up *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_key_up(ee->evas, e->name, e->name, e->string,
+ e->key_compose, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_motion(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Motion *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Button_Down *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ // _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+ evas_event_feed_mouse_down(ee->evas, e->button, EVAS_BUTTON_NONE, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Button_Up *e;
+ Evas_Button_Flags flags = EVAS_BUTTON_NONE;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ //_ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+ evas_event_feed_mouse_up(ee->evas, e->button, flags, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_enter(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Enter *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_mouse_in(ee->evas, e->time, NULL);
+ //_ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_leave(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Leave *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_mouse_out(ee->evas, e->time, NULL);
+ //_ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+ if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
+ if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Wheel *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_mouse_wheel(ee->evas, e->direction, e->z, e->time, NULL);
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_got_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Got_Focus *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ ee->prop.focused = 1;
+ return 1;
+}
+
+static int
+_ecore_evas_directfb_event_lost_focus(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Event_Lost_Focus *e;
+
+ e = event;
+ ee = _ecore_evas_directfb_match(e->win);
+
+ if (!ee) return 1; /* pass on event */
+ ee->prop.focused = 0;
+ return 1;
+}
+
+int
+_ecore_evas_directfb_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ for (i = 0; i < 8; i++)
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+
+
+
+
+int
+_ecore_evas_directfb_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_KEY_DOWN, _ecore_evas_directfb_event_key_down, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_KEY_UP, _ecore_evas_directfb_event_key_up, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_BUTTON_DOWN, _ecore_evas_directfb_event_button_down, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_BUTTON_UP, _ecore_evas_directfb_event_button_up, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_MOTION, _ecore_evas_directfb_event_motion, NULL);
+ ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_ENTER, _ecore_evas_directfb_event_enter, NULL);
+ ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_LEAVE, _ecore_evas_directfb_event_leave, NULL);
+ ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_WHEEL, _ecore_evas_directfb_event_wheel, NULL);
+ ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_GOT_FOCUS, _ecore_evas_directfb_event_got_focus, NULL);
+ ecore_evas_event_handlers[9] = ecore_event_handler_add(ECORE_DIRECTFB_EVENT_LOST_FOCUS, _ecore_evas_directfb_event_lost_focus, NULL);
+ ecore_evas_event_handlers[10] = NULL;
+ ecore_evas_event_handlers[11] = NULL;
+ ecore_evas_event_handlers[12] = NULL;
+
+ return _ecore_evas_init_count;
+}
+
+/* engine functions */
+/********************/
+
+static void
+_ecore_evas_directfb_free(Ecore_Evas *ee)
+{
+ eina_hash_del(ecore_evases_hash, _ecore_evas_directfb_winid_str_get(ee->engine.directfb.window->id), ee);
+ ecore_directfb_window_free(ee->engine.directfb.window);
+ _ecore_evas_directfb_shutdown();
+ ecore_directfb_shutdown();
+}
+
+static void
+_ecore_evas_directfb_move(Ecore_Evas *ee, int x, int y)
+{
+ ecore_directfb_window_move(ee->engine.directfb.window, x, y);
+}
+
+static void
+_ecore_evas_directfb_resize(Ecore_Evas *ee, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ecore_directfb_window_resize(ee->engine.directfb.window, w, h);
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+}
+
+static void
+_ecore_evas_directfb_focus_set(Ecore_Evas *ee, int on __UNUSED__)
+{
+ ecore_directfb_window_focus(ee->engine.directfb.window);
+}
+
+static void
+_ecore_evas_directfb_hide(Ecore_Evas *ee)
+{
+ ecore_directfb_window_hide(ee->engine.directfb.window);
+ ee->should_be_visible = 0;
+}
+
+static void
+_ecore_evas_directfb_show(Ecore_Evas *ee)
+{
+ ecore_directfb_window_show(ee->engine.directfb.window);
+ ee->should_be_visible = 1;
+}
+
+static void
+_ecore_evas_directfb_shaped_set(Ecore_Evas *ee, int shaped)
+{
+ if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped)))
+ return;
+ ee->shaped = shaped;
+ if(ee->shaped)
+ ecore_directfb_window_shaped_set(ee->engine.directfb.window, 1);
+ else
+ ecore_directfb_window_shaped_set(ee->engine.directfb.window, 0);
+
+}
+
+static void
+_ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ if (ee)
+ ee->prop.cursor.object = NULL;
+}
+
+static void
+_ecore_evas_directfb_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+ int x, y;
+
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+ if (obj == NULL)
+ {
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ ecore_directfb_window_cursor_show(ee->engine.directfb.window, 1);
+ return;
+
+ }
+
+ ee->prop.cursor.object = obj;
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+
+ ecore_directfb_window_cursor_show(ee->engine.directfb.window, 0);
+
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_move(ee->prop.cursor.object,x - ee->prop.cursor.hot.x,y - ee->prop.cursor.hot.y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
+}
+
+static void
+_ecore_evas_directfb_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ Evas_Engine_Info_DirectFB *einfo;
+ int w;
+ int h;
+ int resized = 0;
+
+ if (((ee->prop.fullscreen) && (on)) || ((!ee->prop.fullscreen) && (!on)))
+ return;
+
+ if (on)
+ ecore_directfb_window_fullscreen_set(ee->engine.directfb.window, 1);
+ else
+ ecore_directfb_window_fullscreen_set(ee->engine.directfb.window, 0);
+ /* set the new size of the evas */
+ ecore_directfb_window_size_get(ee->engine.directfb.window, &w, &h);
+ if( (ee->w != w) || (ee->h != h))
+ {
+ resized = 1;
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ }
+ einfo = (Evas_Engine_Info_DirectFB *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.surface = ee->engine.directfb.window->surface;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ ee->prop.fullscreen = on;
+ if (resized)
+ {
+ if(ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+}
+
+static void *
+_ecore_evas_directfb_window_get(const Ecore_Evas *ee)
+{
+ return ee->engine.directfb.window;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+static Ecore_Evas_Engine_Func _ecore_directfb_engine_func =
+{
+ _ecore_evas_directfb_free, /* free an ecore_evas */
+ NULL, /* cb resize */
+ NULL, /* cb move */
+ NULL, /* cb show */
+ NULL, /* cb hide */
+ NULL, /* cb delete request */
+ NULL, /* cb destroy */
+ NULL, /* cb focus in */
+ NULL, /* cb focus out */
+ NULL, /* cb sticky */
+ NULL, /* cb unsticky */
+ NULL, /* cb mouse in */
+ NULL, /* cb mouse out */
+ NULL, /* cb pre render */
+ NULL, /* cb post render */
+ _ecore_evas_directfb_move, /* move */
+ NULL, /* managed move */
+ _ecore_evas_directfb_resize, /* resize */
+ NULL, /* move resize */
+ NULL,//_ecore_evas_directfb_rotation_set,/* rotation */
+ _ecore_evas_directfb_shaped_set, /* shaped */
+ _ecore_evas_directfb_show, /* show */
+ _ecore_evas_directfb_hide, /* hide */
+ NULL, /* raise */
+ NULL, /* lower */
+ NULL, /* activate */
+ NULL, /* title set */
+ NULL, /* name class set */
+ NULL, /* size min */
+ NULL, /* size max */
+ NULL, /* size base */
+ NULL, /* size step */
+ _ecore_evas_directfb_object_cursor_set, /* set cursor to an evas object */
+ NULL, /* layer set */
+ _ecore_evas_directfb_focus_set, /* focus */
+ NULL, /* iconified */
+ NULL, /* borderless */
+ NULL, /* override */
+ NULL, /* maximized */
+ _ecore_evas_directfb_fullscreen_set,/* fullscreen */
+ NULL, /* avoid damage */
+ NULL, /* withdrawn */
+ NULL, /* sticky */
+ NULL, /* ignore events */
+ NULL, /* alpha */
+ NULL, //transparent
+
+ NULL // render
+};
+#endif
+
+/* api */
+/*******/
+
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+EAPI Ecore_Evas *
+ecore_evas_directfb_new(const char *disp_name, int windowed, int x, int y, int w, int h)
+{
+ Evas_Engine_Info_DirectFB *einfo;
+ Ecore_Evas *ee;
+ Ecore_DirectFB_Window *window;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("directfb");
+ if (!rmethod) return NULL;
+ if (!ecore_directfb_init(disp_name)) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+ _ecore_evas_directfb_init();
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_directfb_engine_func;
+
+ ee->driver = "directfb";
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+
+ ee->rotation = 0;
+ ee->visible = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = w;
+ ee->h = h;
+ ee->prop.layer = 1;
+ ee->prop.fullscreen = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+ einfo = (Evas_Engine_Info_DirectFB *)evas_engine_info_get(ee->evas);
+
+ window = ecore_directfb_window_new(x,y,w,h);
+ ee->engine.directfb.window = window;
+ if (einfo)
+ {
+ einfo->info.dfb = ecore_directfb_interface_get();
+ einfo->info.surface = window->surface;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+
+ ee->engine.func->fn_render = _ecore_evas_directfb_render;
+ _ecore_evas_register(ee);
+
+ if (!ecore_evases_hash)
+ ecore_evases_hash = eina_hash_string_superfast_new(NULL);
+ eina_hash_add(ecore_evases_hash, _ecore_evas_directfb_winid_str_get(ee->engine.directfb.window->id), ee);
+
+ return ee;
+}
+#else
+EAPI Ecore_Evas *
+ecore_evas_directfb_new(const char *disp_name __UNUSED__, int windowed __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
+{
+ return NULL;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+EAPI Ecore_DirectFB_Window *
+ecore_evas_directfb_window_get(const Ecore_Evas *ee)
+{
+ return (Ecore_DirectFB_Window *) _ecore_evas_directfb_window_get(ee);
+}
+#else
+EAPI Ecore_DirectFB_Window *
+ecore_evas_directfb_window_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return NULL;
+}
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <Ecore.h>
+#include "ecore_private.h"
+#ifdef BUILD_ECORE_EVAS_FB
+#include <Ecore_Fb.h>
+#include <ecore_fb_private.h>
+#endif
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_FB
+static int _ecore_evas_init_count = 0;
+
+static char *ecore_evas_default_display = "0";
+static Eina_List *ecore_evas_input_devices = NULL;
+static Ecore_Event_Handler *ecore_evas_event_handlers[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
+
+static void
+_ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
+{
+ int fbw, fbh;
+
+ ee->mouse.x = x;
+ ee->mouse.y = y;
+ ecore_fb_size_get(&fbw, &fbh);
+ if (ee->prop.cursor.object)
+ {
+ evas_object_show(ee->prop.cursor.object);
+ if (ee->rotation == 0)
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 90)
+ evas_object_move(ee->prop.cursor.object,
+ (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.x,
+ x - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 180)
+ evas_object_move(ee->prop.cursor.object,
+ (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.x,
+ (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.y);
+ else if (ee->rotation == 270)
+ evas_object_move(ee->prop.cursor.object,
+ y - ee->prop.cursor.hot.x,
+ (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.y);
+ }
+ if (ee->rotation == 0)
+ evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL);
+ else if (ee->rotation == 90)
+ evas_event_feed_mouse_move(ee->evas, (fbh - ee->h) + ee->h - y - 1, x, timestamp, NULL);
+ else if (ee->rotation == 180)
+ evas_event_feed_mouse_move(ee->evas, (fbw - ee->w) + ee->w - x - 1, (fbh - ee->h) + ee->h - y - 1, timestamp, NULL);
+ else if (ee->rotation == 270)
+ evas_event_feed_mouse_move(ee->evas, y, (fbw - ee->w) + ee->w - x - 1, timestamp, NULL);
+}
+
+static Ecore_Evas *fb_ee = NULL;
+
+static Ecore_Evas *
+_ecore_evas_fb_match(void)
+{
+ return fb_ee;
+}
+
+static void
+_ecore_evas_fb_lose(void *data __UNUSED__)
+{
+ Ecore_Evas *ee;
+ Eina_List *ll;
+ Ecore_Fb_Input_Device *dev;
+
+ if (fb_ee) fb_ee->visible = 0;
+
+ EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
+ ecore_fb_input_device_listen(dev, 0);
+}
+
+static void
+_ecore_evas_fb_gain(void *data __UNUSED__)
+{
+ Ecore_Evas *ee;
+ Eina_List *ll;
+ Ecore_Fb_Input_Device *dev;
+
+ if (fb_ee)
+ {
+ ee = fb_ee;
+
+ ee->visible = 1;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+
+ EINA_LIST_FOREACH(ecore_evas_input_devices, ll, dev)
+ ecore_fb_input_device_listen(dev, 1);
+}
+
+static int
+_ecore_evas_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Key_Down *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_key_down(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ evas_event_feed_key_up(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Mouse_Button_Down *e;
+ Evas_Button_Flags flags = EVAS_BUTTON_NONE;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
+ if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
+ evas_event_feed_mouse_down(ee->evas, e->button, flags, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Mouse_Button_Up *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ evas_event_feed_mouse_up(ee->evas, e->button, EVAS_BUTTON_NONE, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Mouse_Move *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Fb_Event_Mouse_Wheel *e;
+
+ e = event;
+ ee = _ecore_evas_fb_match();
+ if (!ee) return 1; /* pass on event */
+ _ecore_evas_mouse_move_process_fb(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ return 0; /* dont pass it on */
+}
+
+static int
+_ecore_evas_fb_render(Ecore_Evas *ee)
+{
+ int rend = 0;
+
+ if (ee->visible)
+ {
+ Eina_List *updates;
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ Eina_List *ll;
+ Ecore_Evas *ee2;
+#endif
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+ {
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ rend |= _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+ updates = evas_render_updates(ee->evas);
+ if (updates)
+ {
+ evas_render_updates_free(updates);
+ _ecore_evas_idle_timeout_update(ee);
+ rend = 1;
+ }
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+ }
+ else
+ evas_norender(ee->evas);
+ return rend;
+}
+
+static int
+_ecore_evas_fb_init(int w, int h)
+{
+ Ecore_Fb_Input_Device *device;
+ Ecore_Fb_Input_Device_Cap caps;
+ int mouse_handled = 0;
+ int keyboard_handled = 0;
+
+ DIR *input_dir;
+ struct dirent *input_entry;
+
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+
+ /* register all input devices */
+ input_dir = opendir("/dev/input/");
+ if (!input_dir) return _ecore_evas_init_count;
+
+ while ((input_entry = readdir(input_dir)))
+ {
+ char device_path[256];
+
+ if (strncmp(input_entry->d_name, "event", 5) != 0)
+ continue;
+
+ snprintf(device_path, 256, "/dev/input/%s", input_entry->d_name);
+ if (!(device = ecore_fb_input_device_open(device_path)))
+ continue;
+
+ caps = ecore_fb_input_device_cap_get(device);
+
+ /* Mouse */
+#ifdef HAVE_TSLIB
+ if (caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE)
+#else
+ if ((caps & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE) || (caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
+#endif
+ {
+ ecore_fb_input_device_axis_size_set(device, w, h);
+ ecore_fb_input_device_listen(device,1);
+ ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
+ if (!mouse_handled)
+ {
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
+ ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_WHEEL, _ecore_evas_event_mouse_wheel, NULL);
+ mouse_handled = 1;
+ }
+ }
+ /* Keyboard */
+ else if ((caps & ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS) && !(caps & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE))
+ {
+ ecore_fb_input_device_listen(device,1);
+ ecore_evas_input_devices = eina_list_append(ecore_evas_input_devices, device);
+ if (!keyboard_handled)
+ {
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_FB_EVENT_KEY_DOWN, _ecore_evas_event_key_down, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_FB_EVENT_KEY_UP, _ecore_evas_event_key_up, NULL);
+ keyboard_handled = 1;
+ }
+ }
+ }
+ if (!mouse_handled)
+ {
+ if (ecore_fb_ts_init())
+ {
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL);
+ mouse_handled = 1;
+ }
+ }
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_fb_free(Ecore_Evas *ee)
+{
+ if (fb_ee == ee) fb_ee = NULL;
+ _ecore_evas_fb_shutdown();
+ ecore_fb_shutdown();
+}
+
+static void
+_ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize)
+{
+ Evas_Engine_Info_FB *einfo;
+ int rot_dif;
+
+ if (ee->rotation == rotation) return;
+ einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ rot_dif = ee->rotation - rotation;
+ if (rot_dif < 0) rot_dif = -rot_dif;
+ if (rot_dif != 180)
+ {
+
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ if (!ee->prop.fullscreen)
+ {
+ int tmp;
+
+ tmp = ee->w;
+ ee->w = ee->h;
+ ee->h = tmp;
+ }
+ else
+ {
+ if ((rotation == 0) || (rotation == 180))
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ }
+ ee->rotation = rotation;
+ }
+ else
+ {
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ ee->rotation = rotation;
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ _ecore_evas_mouse_move_process_fb(ee, ee->mouse.x, ee->mouse.y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff));
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ if (ee)
+ ee->prop.cursor.object = NULL;
+}
+
+static void
+_ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+ int x, y;
+
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+ if (obj == NULL)
+ {
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ return;
+ }
+
+ ee->prop.cursor.object = obj;
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
+}
+
+static void
+_ecore_evas_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ Eina_List *l;
+ Ecore_Fb_Input_Device *dev;
+ int resized = 0;
+
+ if (((ee->prop.fullscreen) && (on)) ||
+ ((!ee->prop.fullscreen) && (!on))) return;
+ if (on)
+ {
+ int w, h;
+
+ ee->engine.fb.real_w = ee->w;
+ ee->engine.fb.real_h = ee->h;
+ w = ee->w;
+ h = ee->h;
+ ecore_fb_size_get(&w, &h);
+ if ((w == 0) && (h == 0))
+ {
+ w = ee->w;
+ h = ee->h;
+ }
+ if ((w != ee->w) || (h != ee->h)) resized = 1;
+ ee->w = w;
+ ee->h = h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ if ((ee->engine.fb.real_w != ee->w) || (ee->engine.fb.real_h != ee->h)) resized = 1;
+ ee->w = ee->engine.fb.real_w;
+ ee->h = ee->engine.fb.real_h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ ee->prop.fullscreen = on;
+ EINA_LIST_FOREACH(ecore_evas_input_devices, l, dev)
+ ecore_fb_input_device_axis_size_set(dev, ee->w, ee->h);
+ /* rescale the input device area */
+ if (resized)
+ {
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+}
+
+int
+_ecore_evas_fb_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ for (i = 0; i < 6; i++)
+ {
+ if (ecore_evas_event_handlers[i])
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ }
+ ecore_fb_ts_shutdown();
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+static Ecore_Evas_Engine_Func _ecore_fb_engine_func =
+{
+ _ecore_evas_fb_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_resize,
+ _ecore_evas_move_resize,
+ _ecore_evas_rotation_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_object_cursor_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_fullscreen_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, //transparent
+
+ NULL // render
+};
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_FB
+EAPI Ecore_Evas *
+ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
+{
+ Evas_Engine_Info_FB *einfo;
+ Ecore_Evas *ee;
+
+ int rmethod;
+
+ if (!disp_name)
+ disp_name = ecore_evas_default_display;
+
+ rmethod = evas_render_method_lookup("fb");
+ if (!rmethod) return NULL;
+
+ if (!ecore_fb_init(disp_name)) return NULL;
+ ecore_fb_callback_gain_set(_ecore_evas_fb_gain, NULL);
+ ecore_fb_callback_lose_set(_ecore_evas_fb_lose, NULL);
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_fb_init(w, h);
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func;
+
+ ee->driver = "fb";
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->rotation = rotation;
+ ee->visible = 1;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 1;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 1;
+ ee->prop.fullscreen = 0;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+
+ if ((rotation == 90) || (rotation == 270))
+ {
+ evas_output_size_set(ee->evas, h, w);
+ evas_output_viewport_set(ee->evas, 0, 0, h, w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+ }
+
+ einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.virtual_terminal = 0;
+ einfo->info.device_number = strtol(disp_name, NULL, 10);
+ einfo->info.refresh = 0;
+ einfo->info.rotation = ee->rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+ evas_key_modifier_add(ee->evas, "Shift");
+ evas_key_modifier_add(ee->evas, "Control");
+ evas_key_modifier_add(ee->evas, "Alt");
+ evas_key_modifier_add(ee->evas, "Meta");
+ evas_key_modifier_add(ee->evas, "Hyper");
+ evas_key_modifier_add(ee->evas, "Super");
+ evas_key_lock_add(ee->evas, "Caps_Lock");
+ evas_key_lock_add(ee->evas, "Num_Lock");
+ evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+ ee->engine.func->fn_render = _ecore_evas_buffer_render;
+ _ecore_evas_register(ee);
+ fb_ee = ee;
+
+ evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ evas_focus_in(ee->evas);
+
+ return ee;
+}
+#else
+EAPI Ecore_Evas *
+ecore_evas_fb_new(const char *disp_name __UNUSED__, int rotation __UNUSED__, int w __UNUSED__, int h __UNUSED__)
+{
+ return NULL;
+}
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef _ECORE_EVAS_PRIVATE_H
+#define _ECORE_EVAS_PRIVATE_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+
+#include <Evas.h>
+#include <ecore_private.h>
+#include <Ecore_Input.h>
+#include <Ecore_Input_Evas.h>
+
+#define ECORE_MAGIC_EVAS 0x76543211
+
+#ifndef BUILD_ECORE_DIRECTFB
+# undef BUILD_ECORE_EVAS_DIRECTFB
+#endif
+
+#ifdef BUILD_ECORE_EVAS_X11
+# include "Ecore_X.h"
+# ifdef HAVE_ECORE_X_XCB
+# include <xcb/xcb.h>
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+# include <Evas_Engine_Software_X11.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_XRENDER_XCB
+# include <xcb/render.h>
+# include <Evas_Engine_XRender_X11.h>
+# endif
+# endif
+# ifdef HAVE_ECORE_X_XLIB
+# include <X11/Xlib.h>
+# include <X11/Xutil.h>
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XLIB
+# include <Evas_Engine_Software_X11.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_XRENDER_X11
+# include <X11/extensions/Xrender.h>
+# include <Evas_Engine_XRender_X11.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_OPENGL_X11
+# include <Evas_Engine_GL_X11.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_16_X11
+# include <Evas_Engine_Software_16_X11.h>
+# endif
+# endif
+#endif
+
+#ifdef BUILD_ECORE_EVAS_FB
+# include <Evas_Engine_FB.h>
+#endif
+
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+# include <Evas_Engine_DirectFB.h>
+# include "Ecore_DirectFB.h"
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+# include <Evas_Engine_Buffer.h>
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WIN32
+# include "Ecore_Win32.h"
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
+# include <Evas_Engine_Software_Gdi.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
+# include <Evas_Engine_Software_DDraw.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_DIRECT3D
+# include <Evas_Engine_Direct3D.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_OPENGL_GLEW
+# include <Evas_Engine_GL_Glew.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW
+# include <Evas_Engine_Software_16_DDraw.h>
+# endif
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+# include "Ecore_WinCE.h"
+# include <Evas_Engine_Software_16_WinCE.h>
+#endif
+
+/**
+ Log domain macros and variable
+ **/
+
+extern int _ecore_evas_log_dom;
+
+#ifdef ECORE_EVAS_DEFAULT_LOG_COLOR
+# undef ECORE_EVAS_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_EVAS_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_evas_log_dom, __VA_ARGS__)
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_evas_log_dom, __VA_ARGS__)
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_evas_log_dom, __VA_ARGS__)
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_evas_log_dom, __VA_ARGS__)
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_evas_log_dom, __VA_ARGS__)
+
+
+#define IDLE_FLUSH_TIME 0.5
+#ifndef _ECORE_EVAS_H
+typedef struct _Ecore_Evas Ecore_Evas;
+#endif
+
+typedef struct _Ecore_Evas_Engine Ecore_Evas_Engine;
+typedef struct _Ecore_Evas_Engine_Func Ecore_Evas_Engine_Func;
+
+struct _Ecore_Evas_Engine_Func
+{
+ void (*fn_free) (Ecore_Evas *ee);
+ void (*fn_callback_resize_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_move_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_show_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_hide_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_delete_request_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_destroy_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_focus_in_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_focus_out_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_mouse_in_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_mouse_out_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_sticky_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_unsticky_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_pre_render_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_callback_post_render_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee));
+ void (*fn_move) (Ecore_Evas *ee, int x, int y);
+ void (*fn_managed_move) (Ecore_Evas *ee, int x, int y);
+ void (*fn_resize) (Ecore_Evas *ee, int w, int h);
+ void (*fn_move_resize) (Ecore_Evas *ee, int x, int y, int w, int h);
+ void (*fn_rotation_set) (Ecore_Evas *ee, int rot, int resize);
+ void (*fn_shaped_set) (Ecore_Evas *ee, int shaped);
+ void (*fn_show) (Ecore_Evas *ee);
+ void (*fn_hide) (Ecore_Evas *ee);
+ void (*fn_raise) (Ecore_Evas *ee);
+ void (*fn_lower) (Ecore_Evas *ee);
+ void (*fn_activate) (Ecore_Evas *ee);
+ void (*fn_title_set) (Ecore_Evas *ee, const char *t);
+ void (*fn_name_class_set) (Ecore_Evas *ee, const char *n, const char *c);
+ void (*fn_size_min_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_size_max_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_size_base_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_size_step_set) (Ecore_Evas *ee, int w, int h);
+ void (*fn_object_cursor_set) (Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y);
+ void (*fn_layer_set) (Ecore_Evas *ee, int layer);
+ void (*fn_focus_set) (Ecore_Evas *ee, int on);
+ void (*fn_iconified_set) (Ecore_Evas *ee, int on);
+ void (*fn_borderless_set) (Ecore_Evas *ee, int on);
+ void (*fn_override_set) (Ecore_Evas *ee, int on);
+ void (*fn_maximized_set) (Ecore_Evas *ee, int on);
+ void (*fn_fullscreen_set) (Ecore_Evas *ee, int on);
+ void (*fn_avoid_damage_set) (Ecore_Evas *ee, int on);
+ void (*fn_withdrawn_set) (Ecore_Evas *ee, int withdrawn);
+ void (*fn_sticky_set) (Ecore_Evas *ee, int sticky);
+ void (*fn_ignore_events_set) (Ecore_Evas *ee, int ignore);
+ void (*fn_alpha_set) (Ecore_Evas *ee, int alpha);
+ void (*fn_transparent_set) (Ecore_Evas *ee, int transparent);
+
+ int (*fn_render) (Ecore_Evas *ee);
+};
+
+struct _Ecore_Evas_Engine
+{
+ Ecore_Evas_Engine_Func *func;
+
+#ifdef BUILD_ECORE_EVAS_X11
+ struct {
+ Ecore_X_Window win_root;
+ Eina_List *win_extra;
+ Ecore_X_Pixmap pmap;
+ Ecore_X_Pixmap mask;
+ Ecore_X_GC gc;
+ Ecore_X_XRegion *damages;
+ Ecore_X_Sync_Counter sync_counter;
+ int sync_val; // bigger! this will screw up at 2 billion frames (414 days of continual rendering @ 60fps)
+ int screen_num;
+ int px, py, pw, ph;
+ unsigned char direct_resize : 1;
+ unsigned char using_bg_pixmap : 1;
+ unsigned char managed : 1;
+ unsigned char sync_began : 1;
+ unsigned char sync_cancel : 1;
+ struct {
+ unsigned char modal : 1;
+ unsigned char sticky : 1;
+ unsigned char maximized_v : 1;
+ unsigned char maximized_h : 1;
+ unsigned char shaded : 1;
+ unsigned char skip_taskbar : 1;
+ unsigned char skip_pager : 1;
+ unsigned char fullscreen : 1;
+ unsigned char above : 1;
+ unsigned char below : 1;
+ } state;
+ } x;
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+ struct {
+ int real_w;
+ int real_h;
+ } fb;
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ struct {
+ void *pixels;
+ Evas_Object *image;
+ } buffer;
+#endif
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+ struct {
+ Ecore_DirectFB_Window *window;
+ } directfb;
+#endif
+#ifdef BUILD_ECORE_EVAS_WIN32
+ struct {
+ Ecore_Win32_Window *parent;
+ struct {
+ unsigned char fullscreen : 1;
+ } state;
+ } win32;
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+ struct {
+ Ecore_WinCE_Window *window;
+ struct {
+ unsigned char fullscreen : 1;
+ } state;
+ } wince;
+#endif
+
+ Ecore_Timer *idle_flush_timer;
+};
+
+struct _Ecore_Evas
+{
+ EINA_INLIST;
+ ECORE_MAGIC;
+ Evas *evas;
+ const char *driver;
+ char *name;
+ int x, y, w, h;
+ short rotation;
+ Eina_Bool shaped : 1;
+ Eina_Bool visible : 1;
+ Eina_Bool draw_ok : 1;
+ Eina_Bool should_be_visible : 1;
+ Eina_Bool alpha : 1;
+ Eina_Bool transparent : 1;
+
+ Eina_Hash *data;
+
+ struct {
+ int x, y, w, h;
+ } req;
+
+ struct {
+ int x, y;
+ } mouse;
+
+ struct {
+ int w, h;
+ } expecting_resize;
+
+ struct {
+ char *title;
+ char *name;
+ char *clas;
+ struct {
+ int w, h;
+ } min,
+ max,
+ base,
+ step;
+ struct {
+ Evas_Object *object;
+ int layer;
+ struct {
+ int x, y;
+ } hot;
+ } cursor;
+ int layer;
+ Ecore_Window window;
+ unsigned char avoid_damage;
+ char focused : 1;
+ char iconified : 1;
+ char borderless : 1;
+ char override : 1;
+ char maximized : 1;
+ char fullscreen : 1;
+ char withdrawn : 1;
+ char sticky : 1;
+ char request_pos : 1;
+ } prop;
+
+ struct {
+ void (*fn_resize) (Ecore_Evas *ee);
+ void (*fn_move) (Ecore_Evas *ee);
+ void (*fn_show) (Ecore_Evas *ee);
+ void (*fn_hide) (Ecore_Evas *ee);
+ void (*fn_delete_request) (Ecore_Evas *ee);
+ void (*fn_destroy) (Ecore_Evas *ee);
+ void (*fn_focus_in) (Ecore_Evas *ee);
+ void (*fn_focus_out) (Ecore_Evas *ee);
+ void (*fn_sticky) (Ecore_Evas *ee);
+ void (*fn_unsticky) (Ecore_Evas *ee);
+ void (*fn_mouse_in) (Ecore_Evas *ee);
+ void (*fn_mouse_out) (Ecore_Evas *ee);
+ void (*fn_pre_render) (Ecore_Evas *ee);
+ void (*fn_post_render) (Ecore_Evas *ee);
+ void (*fn_pre_free) (Ecore_Evas *ee);
+ } func;
+
+ Ecore_Evas_Engine engine;
+ Eina_List *sub_ecore_evas;
+
+ unsigned char ignore_events : 1;
+ unsigned char manual_render : 1;
+ unsigned char registered : 1;
+ unsigned char no_comp_sync : 1;
+};
+
+#ifdef BUILD_ECORE_EVAS_X11
+int _ecore_evas_x_shutdown(void);
+#endif
+#ifdef BUILD_ECORE_EVAS_FB
+int _ecore_evas_fb_shutdown(void);
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+int _ecore_evas_buffer_shutdown(void);
+int _ecore_evas_buffer_render(Ecore_Evas *ee);
+#endif
+#ifdef BUILD_ECORE_EVAS_DIRECTFB
+int _ecore_evas_directfb_shutdown(void);
+#endif
+#ifdef BUILD_ECORE_EVAS_WIN32
+int _ecore_evas_win32_shutdown(void);
+#endif
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+int _ecore_evas_wince_shutdown(void);
+#endif
+
+void _ecore_evas_fps_debug_init(void);
+void _ecore_evas_fps_debug_shutdown(void);
+void _ecore_evas_fps_debug_rendertime_add(double t);
+void _ecore_evas_register(Ecore_Evas *ee);
+void _ecore_evas_free(Ecore_Evas *ee);
+void _ecore_evas_idle_timeout_update(Ecore_Evas *ee);
+void _ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp);
+
+extern int _ecore_evas_app_comp_sync;
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Input.h>
+#include <Ecore_Input_Evas.h>
+#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL)
+# include <Ecore_Sdl.h>
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
+# include <Evas_Engine_SDL.h>
+# endif
+# ifdef BUILD_ECORE_EVAS_OPENGL_SDL
+# include <Evas_Engine_GL_SDL.h>
+# endif
+#endif
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+// fixme: 1 sdl window only at a time? seems wrong
+
+#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL)
+
+/* static char *ecore_evas_default_display = "0"; */
+/* static Ecore_List *ecore_evas_input_devices = NULL; */
+
+static int _ecore_evas_init_count = 0;
+
+static Ecore_Evas *sdl_ee = NULL;
+static Ecore_Event_Handler *ecore_evas_event_handlers[4] = {
+ NULL, NULL, NULL, NULL
+};
+
+static const char *ecore_evas_sdl_default = "EFL SDL";
+static int _ecore_evas_fps_debug = 0;
+static Ecore_Poller *ecore_evas_event;
+static Ecore_Evas *ecore_evases = NULL;
+
+static Ecore_Evas *
+_ecore_evas_sdl_match(void)
+{
+ return sdl_ee;
+}
+
+static int
+_ecore_evas_sdl_event_got_focus(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = _ecore_evas_sdl_match();
+
+ if (!ee) return 1;
+ /* pass on event */
+ ee->prop.focused = 1;
+
+ return 0;
+}
+
+static int
+_ecore_evas_sdl_event_lost_focus(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = _ecore_evas_sdl_match();
+
+ if (!ee) return 1;
+ /* pass on event */
+ ee->prop.focused = 0;
+
+ return 0;
+}
+
+static int
+_ecore_evas_sdl_event_video_resize(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Sdl_Event_Video_Resize *e;
+ Ecore_Evas *ee;
+
+ e = event;
+ ee = _ecore_evas_sdl_match();
+
+ if (!ee) return 1; /* pass on event */
+ evas_output_size_set(ee->evas, e->w, e->h);
+
+ return 0;
+}
+
+static int
+_ecore_evas_sdl_event_video_expose(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+{
+ Ecore_Evas *ee;
+ int w;
+ int h;
+
+ ee = _ecore_evas_sdl_match();
+
+ if (!ee) return 1;
+ evas_output_size_get(ee->evas, &w, &h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, w, h);
+
+ return 0;
+}
+
+static int
+_ecore_evas_render(Ecore_Evas *ee)
+{
+ Eina_List *updates;
+
+ updates = evas_render_updates(ee->evas);
+ if (updates)
+ {
+ evas_render_updates_free(updates);
+ _ecore_evas_idle_timeout_update(ee);
+ }
+ return updates ? 1 : 0;
+}
+
+static int
+_ecore_evas_sdl_render(Ecore_Evas *ee)
+{
+ int rend = 0;
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ Eina_List *ll;
+ Ecore_Evas *ee2;
+
+ EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+ {
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ rend |= _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+
+ if (ee->prop.avoid_damage) rend = _ecore_evas_render(ee);
+ else if ((ee->visible) ||
+ ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
+ ((ee->should_be_visible) && (ee->prop.override)))
+ rend |= _ecore_evas_render(ee);
+ else
+ evas_norender(ee->evas);
+
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+ return rend;
+}
+
+static int
+_ecore_evas_sdl_event(void *data __UNUSED__)
+{
+ ecore_sdl_feed_events();
+ return 1;
+}
+
+static int
+_ecore_evas_sdl_init(int w __UNUSED__, int h __UNUSED__)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+
+#ifndef _WIN32
+ if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
+#endif /* _WIN32 */
+ // this is pretty bad: poller? and set poll time? pol time is meant to be
+ // adjustable for things like polling battery state, or amoutn of spare
+ // memory etc.
+ //
+ ecore_evas_event = ecore_poller_add(ECORE_POLLER_CORE, 1, _ecore_evas_sdl_event, NULL);
+ ecore_poller_poll_interval_set(ECORE_POLLER_CORE, 0.006);
+#ifndef _WIN32
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
+#endif /* _WIN32 */
+
+ ecore_event_evas_init();
+
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_SDL_EVENT_GOT_FOCUS, _ecore_evas_sdl_event_got_focus, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_SDL_EVENT_LOST_FOCUS, _ecore_evas_sdl_event_lost_focus, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_SDL_EVENT_RESIZE, _ecore_evas_sdl_event_video_resize, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_SDL_EVENT_EXPOSE, _ecore_evas_sdl_event_video_expose, NULL);
+
+ return _ecore_evas_init_count;
+}
+
+static int
+_ecore_evas_sdl_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ for (i = 0; i < sizeof (ecore_evas_event_handlers) / sizeof (Ecore_Event_Handler*); i++)
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ ecore_event_evas_shutdown();
+ ecore_poller_del(ecore_evas_event);
+ ecore_evas_event = NULL;
+#ifndef _WIN32
+ if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
+#endif /* _WIN32 */
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_sdl_free(Ecore_Evas *ee)
+{
+ if (sdl_ee == ee) sdl_ee = NULL;
+
+ ecore_event_window_unregister(0);
+ _ecore_evas_sdl_shutdown();
+ ecore_sdl_shutdown();
+}
+
+static void
+_ecore_evas_resize(Ecore_Evas *ee, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h)
+{
+ if ((w == ee->w) && (h == ee->h)) return;
+ ee->w = w;
+ ee->h = h;
+
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void
+_ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ if (ee)
+ ee->prop.cursor.object = NULL;
+}
+
+static void
+_ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+ int x, y;
+
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+ if (obj == NULL)
+ {
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ return;
+ }
+
+ ee->prop.cursor.object = obj;
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
+}
+
+static Ecore_Evas_Engine_Func _ecore_sdl_engine_func =
+{
+ _ecore_evas_sdl_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_resize,
+ _ecore_evas_move_resize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_object_cursor_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, //transparent
+
+ NULL // render
+};
+
+static Ecore_Evas*
+_ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha)
+{
+ void *einfo;
+ Ecore_Evas *ee;
+
+ if (!name)
+ name = ecore_evas_sdl_default;
+
+ if (ecore_evases) return NULL;
+
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_sdl_engine_func;
+
+ ee->driver = "sdl";
+ if (name) ee->name = strdup(name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->visible = 1;
+ ee->w = w;
+ ee->h = h;
+
+ ee->prop.max.w = 0;
+ ee->prop.max.h = 0;
+ ee->prop.layer = 0;
+ ee->prop.focused = 1;
+ ee->prop.borderless = 1;
+ ee->prop.override = 1;
+ ee->prop.maximized = 1;
+ ee->prop.fullscreen = fullscreen;
+ ee->prop.withdrawn = 0;
+ ee->prop.sticky = 0;
+ ee->prop.window = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ if (rmethod == evas_render_method_lookup("software_sdl"))
+ {
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
+ einfo = evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ ((Evas_Engine_Info_SDL *)einfo)->info.rotation = 0;
+ ((Evas_Engine_Info_SDL *)einfo)->info.fullscreen = fullscreen;
+ ((Evas_Engine_Info_SDL *)einfo)->info.hwsurface = hwsurface;
+ ((Evas_Engine_Info_SDL *)einfo)->info.noframe = noframe;
+ ((Evas_Engine_Info_SDL *)einfo)->info.alpha = alpha;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+#endif
+ }
+ else if (rmethod == evas_render_method_lookup("gl_sdl"))
+ {
+#ifdef BUILD_ECORE_EVAS_OPENGL_SDL
+ einfo = evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ ((Evas_Engine_Info_GL_SDL *)einfo)->flags.fullscreen = fullscreen;
+ ((Evas_Engine_Info_GL_SDL *)einfo)->flags.noframe = noframe;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+#endif
+ }
+
+ if (!ecore_sdl_init(name))
+ {
+ evas_free(ee->evas);
+ if (ee->name) free(ee->name);
+ free(ee);
+ return NULL;
+ }
+
+ _ecore_evas_sdl_init(w, h);
+
+ ecore_event_window_register(0, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+
+ SDL_ShowCursor(SDL_DISABLE);
+
+ ee->engine.func->fn_render = _ecore_evas_sdl_render;
+ _ecore_evas_register(ee);
+
+ sdl_ee = ee;
+
+ evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+ evas_focus_in(ee->evas);
+
+ return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
+EAPI Ecore_Evas*
+ecore_evas_sdl_new(const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha)
+{
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("software_sdl");
+ if (!rmethod) return NULL;
+
+ ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, hwsurface, noframe, alpha);
+ ee->driver = "sdl";
+ return ee;
+}
+#else
+EAPI Ecore_Evas*
+ecore_evas_sdl_new(const char* name __UNUSED__, int w __UNUSED__, int h __UNUSED__, int fullscreen __UNUSED__, int hwsurface __UNUSED__, int noframe __UNUSED__, int alpha __UNUSED__)
+{
+ ERR("OUTCH !");
+ return NULL;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
+EAPI Ecore_Evas*
+ecore_evas_sdl16_new(const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha)
+{
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("software_16_sdl");
+ if (!rmethod) return NULL;
+
+ ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, hwsurface, noframe, alpha);
+ ee->driver = "software_16_sdl";
+ return ee;
+}
+#else
+EAPI Ecore_Evas*
+ecore_evas_sdl16_new(const char* name __UNUSED__, int w __UNUSED__, int h __UNUSED__, int fullscreen __UNUSED__, int hwsurface __UNUSED__, int noframe __UNUSED__, int alpha __UNUSED__)
+{
+ ERR("OUTCH !");
+ return NULL;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_SDL
+EAPI Ecore_Evas*
+ecore_evas_gl_sdl_new(const char* name, int w, int h, int fullscreen, int noframe)
+{
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("gl_sdl");
+ if (!rmethod) return NULL;
+
+ ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, 0, noframe, 0);
+ ee->driver = "gl_sdl";
+ return ee;
+}
+#else
+EAPI Ecore_Evas*
+ecore_evas_gl_sdl_new(const char* name __UNUSED__, int w __UNUSED__, int h __UNUSED__, int fullscreen __UNUSED__, int noframe __UNUSED__)
+{
+ ERR("OUTCH !");
+ return NULL;
+}
+#endif
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <Ecore.h>
+#include "ecore_private.h"
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+static const char ASSOCIATE_KEY[] = "__Ecore_Evas_Associate";
+
+static void _ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags);
+static void _ecore_evas_object_dissociate(Ecore_Evas *ee, Evas_Object *obj);
+
+
+static Evas_Object *
+_ecore_evas_associate_get(const Ecore_Evas *ee)
+{
+ return ecore_evas_data_get(ee, ASSOCIATE_KEY);
+}
+
+static void
+_ecore_evas_associate_set(Ecore_Evas *ee, Evas_Object *obj)
+{
+ ecore_evas_data_set(ee, ASSOCIATE_KEY, obj);
+}
+
+static void
+_ecore_evas_associate_del(Ecore_Evas *ee)
+{
+ ecore_evas_data_set(ee, ASSOCIATE_KEY, NULL);
+}
+
+static Ecore_Evas *
+_evas_object_associate_get(const Evas_Object *obj)
+{
+ return evas_object_data_get(obj, ASSOCIATE_KEY);
+}
+
+static void
+_evas_object_associate_set(Evas_Object *obj, Ecore_Evas *ee)
+{
+ evas_object_data_set(obj, ASSOCIATE_KEY, ee);
+}
+
+static void
+_evas_object_associate_del(Evas_Object *obj)
+{
+ evas_object_data_del(obj, ASSOCIATE_KEY);
+}
+
+/** Associated Events: ******************************************************/
+
+/* Interceptors Callbacks */
+
+static void
+_ecore_evas_obj_intercept_move(void *data, Evas_Object *obj __UNUSED__, Evas_Coord x, Evas_Coord y)
+{
+ Ecore_Evas *ee = data;
+ // FIXME: account for frame
+ ecore_evas_move(ee, x, y);
+}
+
+static void
+_ecore_evas_obj_intercept_raise(void *data, Evas_Object *obj __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ ecore_evas_raise(ee);
+}
+
+static void
+_ecore_evas_obj_intercept_lower(void *data, Evas_Object *obj __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ ecore_evas_lower(ee);
+}
+
+static void
+_ecore_evas_obj_intercept_stack_above(void *data __UNUSED__, Evas_Object *obj __UNUSED__, Evas_Object *above __UNUSED__)
+{
+ INF("TODO: %s", __FUNCTION__);
+}
+
+static void
+_ecore_evas_obj_intercept_stack_below(void *data __UNUSED__, Evas_Object *obj __UNUSED__, Evas_Object *below __UNUSED__)
+{
+ INF("TODO: %s", __FUNCTION__);
+}
+
+static void
+_ecore_evas_obj_intercept_layer_set(void *data, Evas_Object *obj __UNUSED__, int l)
+{
+ Ecore_Evas *ee = data;
+ ecore_evas_layer_set(ee, l);
+}
+
+/* Event Callbacks */
+
+static void
+_ecore_evas_obj_callback_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ ecore_evas_show(ee);
+}
+
+static void
+_ecore_evas_obj_callback_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ ecore_evas_hide(ee);
+}
+
+static void
+_ecore_evas_obj_callback_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ Evas_Coord ow, oh, w, h;
+
+ evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+ ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+ if ((w != ow) || (h != oh)) /* avoid recursion on ecore_evas_resize side */
+ ecore_evas_resize(ee, ow, oh);
+}
+
+static void
+_ecore_evas_obj_callback_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ Evas_Coord w, h;
+
+ evas_object_size_hint_min_get(obj, &w, &h);
+ ecore_evas_size_min_set(ee, w, h);
+
+ evas_object_size_hint_max_get(obj, &w, &h);
+ if (w < 1) w = -1;
+ if (h < 1) h = -1;
+ ecore_evas_size_max_set(ee, w, h);
+}
+
+static void
+_ecore_evas_obj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ _ecore_evas_object_dissociate(ee, obj);
+ ecore_evas_free(ee);
+}
+
+static void
+_ecore_evas_obj_callback_del_dissociate(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+ _ecore_evas_object_dissociate(ee, obj);
+}
+
+static void
+_ecore_evas_delete_request(Ecore_Evas *ee)
+{
+ Evas_Object *obj = _ecore_evas_associate_get(ee);
+ _ecore_evas_object_dissociate(ee, obj);
+ evas_object_del(obj);
+ ecore_evas_free(ee);
+}
+
+static void
+_ecore_evas_destroy(Ecore_Evas *ee)
+{
+ Evas_Object *obj = _ecore_evas_associate_get(ee);
+ if (!obj)
+ return;
+ _ecore_evas_object_dissociate(ee, obj);
+ evas_object_del(obj);
+}
+
+static void
+_ecore_evas_resize(Ecore_Evas *ee)
+{
+ Evas_Object *obj = _ecore_evas_associate_get(ee);
+ Evas_Coord w, h;
+ ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+ evas_object_resize(obj, w, h);
+}
+
+static void
+_ecore_evas_pre_free(Ecore_Evas *ee)
+{
+ Evas_Object *obj = _ecore_evas_associate_get(ee);
+ if (!obj)
+ return;
+ _ecore_evas_object_dissociate(ee, obj);
+ evas_object_del(obj);
+}
+
+static int
+_ecore_evas_object_evas_check(const char *function, const Ecore_Evas *ee, const Evas_Object *obj)
+{
+ const char *name, *type;
+ Evas *e;
+
+ e = evas_object_evas_get(obj);
+ if (e == ee->evas)
+ return 1;
+
+ name = evas_object_name_get(obj);
+ type = evas_object_type_get(obj);
+
+ ERR("ERROR: %s(): object %p (name=\"%s\", type=\"%s\") evas "
+ "is not the same as this Ecore_Evas evas: %p != %p",
+ function, obj,
+ name ? name : "", type ? type : "", e, ee->evas);
+ fflush(stderr);
+ if (getenv("ECORE_ERROR_ABORT")) abort();
+
+ return 0;
+}
+
+/**
+ * Associate the given object to this ecore evas.
+ *
+ * Association means that operations on one will affect the other, for
+ * example moving the object will move the window, resize the object will
+ * also affect the ecore evas window, hide and show applies as well.
+ *
+ * This is meant to simplify development, since you often need to associate
+ * these events with your "base" objects, background or bottom-most object.
+ *
+ * Be aware that some methods might not be what you would like, deleting
+ * either the window or the object will delete the other. If you want to
+ * change that behavior, let's say to hide window when it's closed, you
+ * must use ecore_evas_callback_delete_request_set() and set your own code,
+ * like ecore_evas_hide(). Just remember that if you override delete_request
+ * and still want to delete the window/object, you must do that yourself.
+ *
+ * Since we now define delete_request, deleting windows will not quit
+ * main loop, if you wish to do so, you should listen for EVAS_CALLBACK_FREE
+ * on the object, that way you get notified and you can call
+ * ecore_main_loop_quit().
+ *
+ * Flags can be OR'ed of:
+ * - ECORE_EVAS_OBJECT_ASSOCIATE_BASE (or 0): to listen to basic events
+ * like delete, resize and move, but no stacking or layer are used.
+ * - ECORE_EVAS_OBJECT_ASSOCIATE_STACK: stacking operations will act
+ * on the Ecore_Evas, not the object. So evas_object_raise() will
+ * call ecore_evas_raise(). Relative operations (stack_above, stack_below)
+ * are still not implemented.
+ * - ECORE_EVAS_OBJECT_ASSOCIATE_LAYER: stacking operations will act
+ * on the Ecore_Evas, not the object. So evas_object_layer_set() will
+ * call ecore_evas_layer_set().
+ * - ECORE_EVAS_OBJECT_ASSOCIATE_DEL: the object delete will delete the
+ * ecore_evas as well as delete_requests on the ecore_evas will delete
+ * etc.
+ *
+ * @param ee The Ecore_Evas to associate to @a obj
+ * @param obj The object to associate to @a ee
+ * @param flags The association flags.
+ * @return 1 on success, 0 otherwise.
+ */
+EAPI int
+ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags)
+{
+ Ecore_Evas *old_ee;
+ Evas_Object *old_obj;
+
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, __FUNCTION__);
+ return 0;
+ }
+
+ CHECK_PARAM_POINTER_RETURN("obj", obj, 0);
+ if (!_ecore_evas_object_evas_check(__FUNCTION__, ee, obj))
+ return 0;
+
+ old_ee = _evas_object_associate_get(obj);;
+ if (old_ee)
+ ecore_evas_object_dissociate(old_ee, obj);
+
+ old_obj = _ecore_evas_associate_get(ee);
+ if (old_obj)
+ ecore_evas_object_dissociate(ee, old_obj);
+
+ _ecore_evas_object_associate(ee, obj, flags);
+ return 1;
+}
+
+/**
+ * Cancel the association set with ecore_evas_object_associate().
+ *
+ * @param ee The Ecore_Evas to dissociate from @a obj
+ * @param obj The object to dissociate from @a ee
+ * @return 1 on success, 0 otherwise.
+ */
+EAPI int
+ecore_evas_object_dissociate(Ecore_Evas *ee, Evas_Object *obj)
+{
+ Ecore_Evas *old_ee;
+ Evas_Object *old_obj;
+
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, __FUNCTION__);
+ return 0;
+ }
+
+ CHECK_PARAM_POINTER_RETURN("obj", obj, 0);
+ old_ee = _evas_object_associate_get(obj);
+ if (ee != old_ee) {
+ ERR("ERROR: trying to dissociate object that is not using "
+ "this Ecore_Evas: %p != %p", ee, old_ee);
+ return 0;
+ }
+
+ old_obj = _ecore_evas_associate_get(ee);
+ if (old_obj != obj) {
+ ERR("ERROR: trying to dissociate object that is not being "
+ "used by this Ecore_Evas: %p != %p", old_obj, obj);
+ return 0;
+ }
+
+ _ecore_evas_object_dissociate(ee, obj);
+
+ return 1;
+}
+
+EAPI Evas_Object *
+ecore_evas_object_associate_get(const Ecore_Evas *ee)
+{
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, __FUNCTION__);
+ return NULL;
+ }
+ return _ecore_evas_associate_get(ee);
+}
+
+static void
+_ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags)
+{
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_SHOW,
+ _ecore_evas_obj_callback_show, ee);
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_HIDE,
+ _ecore_evas_obj_callback_hide, ee);
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_RESIZE,
+ _ecore_evas_obj_callback_resize, ee);
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _ecore_evas_obj_callback_changed_size_hints, ee);
+ if (flags & ECORE_EVAS_OBJECT_ASSOCIATE_DEL)
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_DEL, _ecore_evas_obj_callback_del, ee);
+ else
+ evas_object_event_callback_add
+ (obj, EVAS_CALLBACK_DEL, _ecore_evas_obj_callback_del_dissociate, ee);
+
+ evas_object_intercept_move_callback_add
+ (obj, _ecore_evas_obj_intercept_move, ee);
+
+ if (flags & ECORE_EVAS_OBJECT_ASSOCIATE_STACK)
+ {
+ evas_object_intercept_raise_callback_add
+ (obj, _ecore_evas_obj_intercept_raise, ee);
+ evas_object_intercept_lower_callback_add
+ (obj, _ecore_evas_obj_intercept_lower, ee);
+ evas_object_intercept_stack_above_callback_add
+ (obj, _ecore_evas_obj_intercept_stack_above, ee);
+ evas_object_intercept_stack_below_callback_add
+ (obj, _ecore_evas_obj_intercept_stack_below, ee);
+ }
+
+ if (flags & ECORE_EVAS_OBJECT_ASSOCIATE_LAYER)
+ evas_object_intercept_layer_set_callback_add
+ (obj, _ecore_evas_obj_intercept_layer_set, ee);
+
+ if (flags & ECORE_EVAS_OBJECT_ASSOCIATE_DEL)
+ {
+ ecore_evas_callback_delete_request_set(ee, _ecore_evas_delete_request);
+ ecore_evas_callback_destroy_set(ee, _ecore_evas_destroy);
+ }
+ ecore_evas_callback_pre_free_set(ee, _ecore_evas_pre_free);
+ ecore_evas_callback_resize_set(ee, _ecore_evas_resize);
+
+ _evas_object_associate_set(obj, ee);
+ _ecore_evas_associate_set(ee, obj);
+}
+
+static void
+_ecore_evas_object_dissociate(Ecore_Evas *ee, Evas_Object *obj)
+{
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_SHOW,
+ _ecore_evas_obj_callback_show, ee);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_HIDE,
+ _ecore_evas_obj_callback_hide, ee);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_RESIZE,
+ _ecore_evas_obj_callback_resize, ee);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _ecore_evas_obj_callback_changed_size_hints, ee);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_DEL, _ecore_evas_obj_callback_del, ee);
+ evas_object_event_callback_del_full
+ (obj, EVAS_CALLBACK_DEL, _ecore_evas_obj_callback_del_dissociate, ee);
+
+ evas_object_intercept_move_callback_del
+ (obj, _ecore_evas_obj_intercept_move);
+
+ evas_object_intercept_raise_callback_del
+ (obj, _ecore_evas_obj_intercept_raise);
+ evas_object_intercept_lower_callback_del
+ (obj, _ecore_evas_obj_intercept_lower);
+ evas_object_intercept_stack_above_callback_del
+ (obj, _ecore_evas_obj_intercept_stack_above);
+ evas_object_intercept_stack_below_callback_del
+ (obj, _ecore_evas_obj_intercept_stack_below);
+
+ evas_object_intercept_layer_set_callback_del
+ (obj, _ecore_evas_obj_intercept_layer_set);
+
+ if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+ {
+ ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, __FUNCTION__);
+ }
+ else
+ {
+ if (ee->func.fn_delete_request == _ecore_evas_delete_request)
+ ecore_evas_callback_delete_request_set(ee, NULL);
+ if (ee->func.fn_destroy == _ecore_evas_destroy)
+ ecore_evas_callback_destroy_set(ee, NULL);
+ if (ee->func.fn_resize == _ecore_evas_resize)
+ ecore_evas_callback_resize_set(ee, NULL);
+ if (ee->func.fn_pre_free == _ecore_evas_pre_free)
+ ecore_evas_callback_pre_free_set(ee, NULL);
+
+ _ecore_evas_associate_del(ee);
+ }
+
+ _evas_object_associate_del(obj);
+}
+
+/**
+ * Helper ecore_getopt callback to list available Ecore_Evas engines.
+ *
+ * This will list all available engines except buffer, this is useful
+ * for applications to let user choose how they should create windows
+ * with ecore_evas_new().
+ *
+ * @c callback_data value is used as @c FILE* and says where to output
+ * messages, by default it is @c stdout. You can specify this value
+ * with ECORE_GETOPT_CALLBACK_FULL() or ECORE_GETOPT_CALLBACK_ARGS().
+ *
+ * If there is a boolean storage provided, then it is marked with 1
+ * when this option is executed.
+ */
+unsigned char
+ecore_getopt_callback_ecore_evas_list_engines(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc __UNUSED__, const char *str __UNUSED__, void *data, Ecore_Getopt_Value *storage)
+{
+ Eina_List *lst, *n;
+ const char *engine;
+ FILE *fp = data;
+
+ if (!fp)
+ fp = stdout;
+
+ lst = ecore_evas_engines_get();
+
+ fputs("supported engines:\n", fp);
+ EINA_LIST_FOREACH(lst, n, engine)
+ if (strcmp(engine, "buffer") != 0)
+ fprintf(fp, "\t%s\n", engine);
+
+ ecore_evas_engines_free(lst);
+
+ if (storage->boolp)
+ *storage->boolp = 1;
+
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h> /* for NULL */
+
+#include <Ecore.h>
+#include "ecore_private.h"
+#ifdef BUILD_ECORE_EVAS_WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+# include <Ecore_Win32.h>
+# include <ecore_win32_private.h>
+#endif /* BUILD_ECORE_EVAS_WIN32 */
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_WIN32
+
+#define ECORE_EVAS_EVENT_COUNT 8
+
+static int _ecore_evas_init_count = 0;
+
+static Ecore_Event_Handler *ecore_evas_event_handlers[ECORE_EVAS_EVENT_COUNT];
+
+static int _ecore_evas_win32_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_win32_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_win32_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_win32_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_win32_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_win32_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_win32_event_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_win32_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+/* Private functions */
+
+static int
+_ecore_evas_win32_render(Ecore_Evas *ee)
+{
+ int rend = 0;
+ Eina_List *updates = NULL;
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ Eina_List *ll;
+ Ecore_Evas *ee2;
+
+ EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+ {
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ rend |= _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+ if (ee->prop.avoid_damage)
+ {
+ updates = evas_render_updates(ee->evas);
+ if (updates) evas_render_updates_free(updates);
+ }
+ else if ((ee->visible) ||
+ ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
+ ((ee->should_be_visible) && (ee->prop.override)))
+ {
+ if (ee->shaped)
+ {
+ updates = evas_render_updates(ee->evas);
+ if (updates) evas_render_updates_free(updates);
+ }
+ else
+ {
+ updates = evas_render_updates(ee->evas);
+ if (updates) evas_render_updates_free(updates);
+ }
+ }
+ else
+ evas_norender(ee->evas);
+ if (updates) rend = 1;
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+ return rend;
+}
+
+static int
+_ecore_evas_win32_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1)
+ return _ecore_evas_init_count;
+
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_WIN32_EVENT_MOUSE_IN, _ecore_evas_win32_event_mouse_in, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_WIN32_EVENT_MOUSE_OUT, _ecore_evas_win32_event_mouse_out, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_DAMAGE, _ecore_evas_win32_event_window_damage, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_DESTROY, _ecore_evas_win32_event_window_destroy, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_SHOW, _ecore_evas_win32_event_window_show, NULL);
+ ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_HIDE, _ecore_evas_win32_event_window_hide, NULL);
+ ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_CONFIGURE, _ecore_evas_win32_event_window_configure, NULL);
+ ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST, _ecore_evas_win32_event_window_delete_request, NULL);
+
+ ecore_event_evas_init();
+ return _ecore_evas_init_count;
+}
+
+int
+_ecore_evas_win32_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ for (i = 0; i < ECORE_EVAS_EVENT_COUNT; i++)
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ ecore_event_evas_shutdown();
+ }
+
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+
+ return _ecore_evas_init_count;
+}
+
+static int
+_ecore_evas_win32_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Mouse_In *e;
+
+ INF("mouse in");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+
+ if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
+ /* FIXME to do */
+/* _ecore_evas_x_modifier_locks_update(ee, e->modifiers); */
+ evas_event_feed_mouse_in(ee->evas, e->time, NULL);
+ evas_focus_in(ee->evas);
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+
+ return 1;
+}
+
+static int
+_ecore_evas_win32_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Mouse_Out *e;
+
+ INF("mouse out");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+
+ /* FIXME to do */
+/* _ecore_evas_x_modifier_locks_update(ee, e->modifiers); */
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+
+ evas_event_feed_mouse_out(ee->evas, e->time, NULL);
+ if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
+ if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
+
+ return 1;
+}
+
+static int
+_ecore_evas_win32_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Window_Damage *e;
+
+ INF("window damage");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+
+ if (ee->prop.avoid_damage)
+ {
+#ifdef _MSC_VER
+# pragma message ("[ECORE] [WIN32] No Region code")
+#else
+# warning [ECORE] [WIN32] No Region code
+#endif /* ! _MSC_VER */
+ }
+ else
+ {
+ if (ee->rotation == 0)
+ evas_damage_rectangle_add(ee->evas,
+ e->x,
+ e->y,
+ e->width,
+ e->height);
+ else if (ee->rotation == 90)
+ evas_damage_rectangle_add(ee->evas,
+ ee->h - e->y - e->height,
+ e->x,
+ e->height,
+ e->width);
+ else if (ee->rotation == 180)
+ evas_damage_rectangle_add(ee->evas,
+ ee->w - e->x - e->width,
+ ee->h - e->y - e->height,
+ e->width,
+ e->height);
+ else if (ee->rotation == 270)
+ evas_damage_rectangle_add(ee->evas,
+ e->y,
+ ee->w - e->x - e->width,
+ e->height,
+ e->width);
+ }
+
+ return 1;
+}
+
+static int
+_ecore_evas_win32_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Window_Destroy *e;
+
+ INF("window destroy");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+ if (ee->func.fn_destroy) ee->func.fn_destroy(ee);
+ ecore_evas_free(ee);
+
+ return 1;
+}
+
+static int
+_ecore_evas_win32_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Window_Show *e;
+
+ INF("window show");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+ if (ee->visible) return 0; /* dont pass it on */
+ ee->visible = 1;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+
+ return 1;
+}
+
+static int
+_ecore_evas_win32_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Window_Hide *e;
+
+ INF("window hide");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+ if (!ee->visible) return 0; /* dont pass it on */
+ ee->visible = 0;
+ if (ee->func.fn_hide) ee->func.fn_hide(ee);
+
+ return 1;
+}
+
+static int
+_ecore_evas_win32_event_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Window_Configure *e;
+
+ INF("window configure");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+
+ if ((ee->x != e->x) || (ee->y != e->y))
+ {
+ ee->x = e->x;
+ ee->y = e->y;
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+
+ if ((ee->w != e->width) || (ee->h != e->height))
+ {
+ ee->w = e->width;
+ ee->h = e->height;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, 1);
+ }
+ /* FIXME: to do... */
+/* if (ee->shaped) */
+/* _ecore_evas_x_resize_shape(ee); */
+ if ((ee->expecting_resize.w > 0) &&
+ (ee->expecting_resize.h > 0))
+ {
+ if ((ee->expecting_resize.w == ee->w) &&
+ (ee->expecting_resize.h == ee->h))
+ _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_win32_current_time_get());
+ ee->expecting_resize.w = 0;
+ ee->expecting_resize.h = 0;
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+
+ return 1;
+}
+
+static int
+_ecore_evas_win32_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_Win32_Event_Window_Delete_Request *e;
+
+ INF("window delete request");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if ((Ecore_Window)e->window != ee->prop.window) return 1;
+ if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
+
+ INF(" * ee event delete\n");
+ return 1;
+}
+
+
+/* Ecore_Evas interface */
+
+static void
+_ecore_evas_win32_free(Ecore_Evas *ee)
+{
+ INF("ecore evas free");
+
+ ecore_win32_window_free((struct _Ecore_Win32_Window *)ee->prop.window);
+ ecore_event_window_unregister(ee->prop.window);
+ _ecore_evas_win32_shutdown();
+ ecore_win32_shutdown();
+}
+
+static void
+_ecore_evas_win32_callback_delete_request_set(Ecore_Evas *ee,
+ void (*func) (Ecore_Evas *ee))
+{
+ ee->func.fn_delete_request = func;
+}
+
+static void
+_ecore_evas_win32_move(Ecore_Evas *ee, int x, int y)
+{
+ INF("ecore evas move (%dx%d)", x, y);
+
+ if ((x != ee->x) || (y != ee->y))
+ {
+ ee->x = x;
+ ee->y = y;
+ ecore_win32_window_move((struct _Ecore_Win32_Window *)ee->prop.window,
+ x, y);
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+}
+
+static void
+_ecore_evas_win32_resize(Ecore_Evas *ee, int width, int height)
+{
+ INF("ecore evas resize (%dx%d)", width, height);
+
+ if ((ee->w != width) || (ee->h != height))
+ {
+ ee->w = width;
+ ee->h = height;
+ ecore_win32_window_resize((struct _Ecore_Win32_Window *)ee->prop.window,
+ width, height);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ /* FIXME: damage and shape */
+
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+}
+
+static void
+_ecore_evas_win32_move_resize(Ecore_Evas *ee, int x, int y, int width, int height)
+{
+ INF("ecore evas resize (%dx%d %dx%d)", x, y, width, height);
+
+ if ((ee->w != width) || (ee->h != height) || (x != ee->x) || (y != ee->y))
+ {
+ int change_size = 0;
+ int change_pos = 0;
+
+ if ((ee->w != width) || (ee->h != height)) change_size = 1;
+ if ((x != ee->x) || (y != ee->y)) change_pos = 1;
+
+ ee->x = x;
+ ee->y = y;
+ ee->w = width;
+ ee->h = height;
+ ecore_win32_window_move_resize((struct _Ecore_Win32_Window *)ee->prop.window,
+ x, y, width, height);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ /* FIXME: damage and shape */
+ if (change_pos)
+ {
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+ if (change_size)
+ {
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ }
+}
+
+static void
+_ecore_evas_win32_rotation_set_internal(Ecore_Evas *ee, int rotation)
+{
+ int rot_dif;
+
+ rot_dif = ee->rotation - rotation;
+ if (rot_dif < 0) rot_dif = -rot_dif;
+
+ if (rot_dif != 180)
+ {
+ int minw, minh, maxw, maxh, basew, baseh, stepw, steph;
+
+ if (!ee->prop.fullscreen)
+ {
+ ecore_win32_window_resize((struct _Ecore_Win32_Window *)ee->prop.window,
+ ee->h, ee->w);
+ ee->expecting_resize.w = ee->h;
+ ee->expecting_resize.h = ee->w;
+ }
+ else
+ {
+ int w, h;
+
+ ecore_win32_window_size_get((struct _Ecore_Win32_Window *)ee->prop.window,
+ &w, &h);
+ ecore_win32_window_resize((struct _Ecore_Win32_Window *)ee->prop.window,
+ h, w);
+ if ((rotation == 0) || (rotation == 180))
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ ecore_evas_size_min_get(ee, &minw, &minh);
+ ecore_evas_size_max_get(ee, &maxw, &maxh);
+ ecore_evas_size_base_get(ee, &basew, &baseh);
+ ecore_evas_size_step_get(ee, &stepw, &steph);
+ ee->rotation = rotation;
+ ecore_evas_size_min_set(ee, minh, minw);
+ ecore_evas_size_max_set(ee, maxh, maxw);
+ ecore_evas_size_base_set(ee, baseh, basew);
+ ecore_evas_size_step_set(ee, steph, stepw);
+ _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_win32_current_time_get());
+ }
+ else
+ {
+ ee->rotation = rotation;
+ _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_win32_current_time_get());
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+}
+
+static void
+_ecore_evas_win32_rotation_set(Ecore_Evas *ee, int rotation, int resize)
+{
+ INF("ecore evas rotation: %s", rotation ? "yes" : "no");
+
+ if (ee->rotation == rotation) return;
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
+ if (!strcmp(ee->driver, "software_gdi"))
+ {
+ Evas_Engine_Info_Software_Gdi *einfo;
+
+ einfo = (Evas_Engine_Info_Software_Gdi *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ _ecore_evas_win32_rotation_set_internal(ee, rotation);
+ }
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
+ if (!strcmp(ee->driver, "software_ddraw"))
+ {
+ Evas_Engine_Info_Software_DDraw *einfo;
+
+ einfo = (Evas_Engine_Info_Software_DDraw *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ einfo->info.rotation = rotation;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ _ecore_evas_win32_rotation_set_internal(ee, rotation);
+ }
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_DDRAW */
+}
+
+static void
+_ecore_evas_win32_show(Ecore_Evas *ee)
+{
+ INF("ecore evas show");
+
+ ee->should_be_visible = 1;
+ if (ee->prop.avoid_damage)
+ _ecore_evas_win32_render(ee);
+ ecore_win32_window_show((struct _Ecore_Win32_Window *)ee->prop.window);
+/* if (ee->prop.fullscreen) */
+/* ecore_win32_window_focus(ee->prop.window); */
+}
+
+static void
+_ecore_evas_win32_hide(Ecore_Evas *ee)
+{
+ INF("ecore evas hide");
+
+ ecore_win32_window_hide((struct _Ecore_Win32_Window *)ee->prop.window);
+ ee->should_be_visible = 0;
+}
+
+static void
+_ecore_evas_win32_raise(Ecore_Evas *ee)
+{
+ INF("ecore evas raise");
+
+ if (!ee->prop.fullscreen)
+ ecore_win32_window_raise((struct _Ecore_Win32_Window *)ee->prop.window);
+ else
+ ecore_win32_window_raise((struct _Ecore_Win32_Window *)ee->prop.window);
+}
+
+static void
+_ecore_evas_win32_lower(Ecore_Evas *ee)
+{
+ INF("ecore evas lower");
+
+ if (!ee->prop.fullscreen)
+ ecore_win32_window_lower((struct _Ecore_Win32_Window *)ee->prop.window);
+ else
+ ecore_win32_window_lower((struct _Ecore_Win32_Window *)ee->prop.window);
+}
+
+static void
+_ecore_evas_win32_activate(Ecore_Evas *ee)
+{
+ INF("ecore evas activate");
+
+ ecore_win32_window_focus_set((struct _Ecore_Win32_Window *)ee->prop.window);
+}
+
+static void
+_ecore_evas_win32_title_set(Ecore_Evas *ee, const char *title)
+{
+ INF("ecore evas title set");
+
+ if (ee->prop.title) free(ee->prop.title);
+ ee->prop.title = NULL;
+ if (title) ee->prop.title = strdup(title);
+ ecore_win32_window_title_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ ee->prop.title);
+}
+
+static void
+_ecore_evas_win32_size_min_set(Ecore_Evas *ee, int width, int height)
+{
+ if (width < 0) width = 0;
+ if (height < 0) height = 0;
+ if ((ee->prop.min.w == width) && (ee->prop.min.h == height)) return;
+ ee->prop.min.w = width;
+ ee->prop.min.h = height;
+ ecore_win32_window_size_min_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ width, height);
+}
+
+static void
+_ecore_evas_win32_size_max_set(Ecore_Evas *ee, int width, int height)
+{
+ if (width < 0) width = 0;
+ if (height < 0) height = 0;
+ if ((ee->prop.max.w == width) && (ee->prop.max.h == height)) return;
+ ee->prop.max.w = width;
+ ee->prop.max.h = height;
+ ecore_win32_window_size_max_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ width, height);
+}
+
+static void
+_ecore_evas_win32_size_base_set(Ecore_Evas *ee, int width, int height)
+{
+ if (width < 0) width = 0;
+ if (height < 0) height = 0;
+ if ((ee->prop.base.w == width) && (ee->prop.base.h == height)) return;
+ ee->prop.base.w = width;
+ ee->prop.base.h = height;
+ ecore_win32_window_size_base_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ width, height);
+}
+
+static void
+_ecore_evas_win32_size_step_set(Ecore_Evas *ee, int width, int height)
+{
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+ if ((ee->prop.step.w == width) && (ee->prop.step.h == height)) return;
+ ee->prop.step.w = width;
+ ee->prop.step.h = height;
+ ecore_win32_window_size_step_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ width, height);
+}
+
+static void
+_ecore_evas_win32_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+#if 0
+ int x, y;
+
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+ if (obj == NULL)
+ {
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ ecore_win32_window_cursor_show(ee->prop.window, 1);
+ return;
+ }
+
+ ee->prop.cursor.object = obj;
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+
+ ecore_win32_window_cursor_show(ee->prop.window, 0);
+
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+#endif
+}
+
+static void
+_ecore_evas_win32_focus_set(Ecore_Evas *ee, int on __UNUSED__)
+{
+ ecore_win32_window_focus_set((struct _Ecore_Win32_Window *)ee->prop.window);
+}
+
+static void
+_ecore_evas_win32_iconified_set(Ecore_Evas *ee, int on)
+{
+/* if (((ee->prop.borderless) && (on)) || */
+/* ((!ee->prop.borderless) && (!on))) return; */
+ ee->prop.iconified = on;
+ ecore_win32_window_iconified_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ ee->prop.iconified);
+}
+
+static void
+_ecore_evas_win32_borderless_set(Ecore_Evas *ee, int on)
+{
+ if (((ee->prop.borderless) && (on)) ||
+ ((!ee->prop.borderless) && (!on))) return;
+ ee->prop.borderless = on;
+ ecore_win32_window_borderless_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ ee->prop.borderless);
+}
+
+static void
+_ecore_evas_win32_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ struct _Ecore_Win32_Window *window;
+
+ INF("ecore evas fullscreen set");
+
+ if ((ee->engine.win32.state.fullscreen && on) ||
+ (!ee->engine.win32.state.fullscreen && !on))
+ return;
+
+ ee->engine.win32.state.fullscreen = on;
+ ee->prop.fullscreen = on;
+
+ window = (struct _Ecore_Win32_Window *)ee->prop.window;
+
+ if (on != 0)
+ {
+ ecore_win32_window_shape_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ 0, 0, NULL);
+ ecore_win32_window_fullscreen_set((struct _Ecore_Win32_Window *)ee->prop.window,
+ on);
+ }
+ else
+ {
+ ecore_win32_window_fullscreen_set(window, on);
+ ecore_win32_window_shape_set(window,
+ window->shape.width,
+ window->shape.height,
+ window->shape.mask);
+ }
+
+ /* Nothing to be done for the GDI backend at the evas level */
+
+#ifdef BUILD_ECORE_EVAS_SOFTWRE_DDRAW
+ if (strcmp(ee->driver, "software_ddraw") == 0)
+ {
+ Evas_Engine_Info_Software_DDraw *einfo;
+
+ einfo = (Evas_Engine_Info_Software_DDraw *)evas_engine_info_get(ecore_evas_get(ee));
+ if (einfo != NULL)
+ {
+ einfo->info.fullscreen = !!on;
+/* einfo->info.layered = window->shape.layered; */
+ evas_engine_info_set(ecore_evas_get(ee), (Evas_Engine_Info *)einfo);
+ }
+ }
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_DDRAW */
+
+#ifdef BUILD_ECORE_EVAS_DIRECT3D
+ if (strcmp(ee->driver, "direct3d") == 0)
+ {
+ Evas_Engine_Info_Direct3D *einfo;
+
+ einfo = (Evas_Engine_Info_Direct3D *)evas_engine_info_get(ecore_evas_get(ee));
+ if (einfo != NULL)
+ {
+ einfo->info.fullscreen = !!on;
+ einfo->info.layered = window->shape.layered;
+ evas_engine_info_set(ecore_evas_get(ee), (Evas_Engine_Info *)einfo);
+ }
+ }
+#endif /* BUILD_ECORE_EVAS_DIRECT3D */
+}
+
+
+static Ecore_Evas_Engine_Func _ecore_win32_engine_func =
+{
+ _ecore_evas_win32_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_win32_callback_delete_request_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_win32_move,
+ NULL,
+ _ecore_evas_win32_resize,
+ _ecore_evas_win32_move_resize,
+ _ecore_evas_win32_rotation_set,
+ NULL, /* _ecore_evas_x_shaped_set */
+ _ecore_evas_win32_show,
+ _ecore_evas_win32_hide,
+ _ecore_evas_win32_raise,
+ _ecore_evas_win32_lower,
+ _ecore_evas_win32_activate,
+ _ecore_evas_win32_title_set,
+ NULL, /* _ecore_evas_x_name_class_set */
+ _ecore_evas_win32_size_min_set,
+ _ecore_evas_win32_size_max_set,
+ _ecore_evas_win32_size_base_set,
+ _ecore_evas_win32_size_step_set,
+ _ecore_evas_win32_cursor_set,
+ NULL, /* _ecore_evas_x_layer_set */
+ _ecore_evas_win32_focus_set,
+ _ecore_evas_win32_iconified_set,
+ _ecore_evas_win32_borderless_set,
+ NULL, /* _ecore_evas_x_override_set */
+ NULL,
+ _ecore_evas_win32_fullscreen_set,
+ NULL, /* _ecore_evas_x_avoid_damage_set */
+ NULL, /* _ecore_evas_x_withdrawn_set */
+ NULL, /* _ecore_evas_x_sticky_set */
+ NULL, /* _ecore_evas_x_ignore_events_set */
+ NULL, /* _ecore_evas_x_alpha_set */
+ NULL, //transparent
+
+ NULL // render
+};
+
+#endif /* BUILD_ECORE_EVAS_WIN32 */
+
+/* API */
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
+static int
+_ecore_evas_engine_software_gdi_init(Ecore_Evas *ee)
+{
+ Evas_Engine_Info_Software_Gdi *einfo;
+ const char *driver;
+ int rmethod;
+
+ driver = "software_gdi";
+
+ rmethod = evas_render_method_lookup(driver);
+ if (!rmethod)
+ return 0;
+
+ ee->driver = driver;
+ evas_output_method_set(ee->evas, rmethod);
+
+ einfo = (Evas_Engine_Info_Software_Gdi *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ /* FIXME: REDRAW_DEBUG missing for now */
+ einfo->info.window = ((struct _Ecore_Win32_Window *)ee->prop.window)->window;
+ einfo->info.mask = NULL;
+ einfo->info.depth = ecore_win32_screen_depth_get();
+ einfo->info.rotation = 0;
+ einfo->info.fullscreen = 0;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+
+ return 1;
+}
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
+static int
+_ecore_evas_engine_software_ddraw_init(Ecore_Evas *ee)
+{
+ Evas_Engine_Info_Software_DDraw *einfo;
+ const char *driver;
+ int rmethod;
+
+ driver = "software_ddraw";
+
+ rmethod = evas_render_method_lookup(driver);
+ if (!rmethod)
+ return 0;
+
+ ee->driver = driver;
+ evas_output_method_set(ee->evas, rmethod);
+
+ einfo = (Evas_Engine_Info_Software_DDraw *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ /* FIXME: REDRAW_DEBUG missing for now */
+ einfo->info.window = ((struct _Ecore_Win32_Window *)ee->prop.window)->window;
+ einfo->info.depth = ecore_win32_screen_depth_get();
+ einfo->info.rotation = 0;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+
+ return 1;
+}
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_DDRAW */
+
+#ifdef BUILD_ECORE_EVAS_DIRECT3D
+static int
+_ecore_evas_engine_direct3d_init(Ecore_Evas *ee)
+{
+ Evas_Engine_Info_Direct3D *einfo;
+ const char *driver;
+ int rmethod;
+
+ driver = "direct3d";
+
+ rmethod = evas_render_method_lookup(driver);
+ if (!rmethod)
+ return 0;
+
+ ee->driver = driver;
+ evas_output_method_set(ee->evas, rmethod);
+
+ einfo = (Evas_Engine_Info_Direct3D *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ /* FIXME: REDRAW_DEBUG missing for now */
+ einfo->info.window = ((struct _Ecore_Win32_Window *)ee->prop.window)->window;
+ einfo->info.depth = ecore_win32_screen_depth_get();
+ einfo->info.rotation = 0;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+
+ return 1;
+}
+#endif /* BUILD_ECORE_EVAS_DIRECT3D */
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_GLEW
+static int
+_ecore_evas_engine_opengl_glew_init(Ecore_Evas *ee)
+{
+ Evas_Engine_Info_GL_Glew *einfo;
+ const char *driver;
+ int rmethod;
+
+ driver = "gl_glew";
+
+ rmethod = evas_render_method_lookup(driver);
+ if (!rmethod)
+ return 0;
+
+ ee->driver = driver;
+ evas_output_method_set(ee->evas, rmethod);
+
+ einfo = (Evas_Engine_Info_GL_Glew *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ /* FIXME: REDRAW_DEBUG missing for now */
+ einfo->info.window = ((struct _Ecore_Win32_Window *)ee->prop.window)->window;
+ einfo->info.depth = ecore_win32_screen_depth_get();
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+
+ return 1;
+}
+#endif /* BUILD_ECORE_EVAS_OPENGL_GLEW */
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW
+static int
+_ecore_evas_engine_software_16_ddraw_init(Ecore_Evas *ee)
+{
+ Evas_Engine_Info_Software_DDraw *einfo;
+ const char *driver;
+ int rmethod;
+
+ driver = "software_16_ddraw";
+
+ rmethod = evas_render_method_lookup(driver);
+ if (!rmethod)
+ return 0;
+
+ ee->driver = driver;
+ evas_output_method_set(ee->evas, rmethod);
+
+ if (ecore_win32_screen_depth_get() != 16)
+ return 0;
+
+ einfo = (Evas_Engine_Info_Software_16_DDraw *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ /* FIXME: REDRAW_DEBUG missing for now */
+ einfo->info.window = ((struct _Ecore_Win32_Window *)ee->prop.window)->window;
+ einfo->info.depth = ecore_win32_screen_depth_get();
+ einfo->info.rotation = 0;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+
+ return 1;
+}
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW */
+
+#ifdef BUILD_ECORE_EVAS_WIN32
+static Ecore_Evas *
+_ecore_evas_win32_new_internal(int (*_ecore_evas_engine_init)(Ecore_Evas *ee),
+ Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ Ecore_Evas *ee;
+
+ if (!ecore_win32_init())
+ return NULL;
+
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee)
+ return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_win32_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_win32_engine_func;
+
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = width;
+ ee->h = height;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+ ee->prop.request_pos = 0;
+ ee->prop.sticky = 0;
+ /* FIXME: sticky to add */
+ ee->prop.window = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_size_set(ee->evas, width, height);
+ evas_output_viewport_set(ee->evas, 0, 0, width, height);
+
+ ee->engine.win32.parent = parent;
+ ee->prop.window = (Ecore_Window)ecore_win32_window_new(parent, x, y, width, height);
+ if (!ee->prop.window)
+ {
+ _ecore_evas_win32_shutdown();
+ free(ee);
+ return NULL;
+ }
+
+ if (!_ecore_evas_engine_init(ee))
+ {
+ _ecore_evas_win32_shutdown();
+ free(ee);
+ return NULL;
+ }
+
+ ee->engine.func->fn_render = _ecore_evas_win32_render;
+ _ecore_evas_register(ee);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, _ecore_evas_mouse_move_process);
+
+ return ee;
+}
+
+#endif /* BUILD_ECORE_EVAS_WIN32 */
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
+
+EAPI Ecore_Evas *
+ecore_evas_software_gdi_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return _ecore_evas_win32_new_internal(_ecore_evas_engine_software_gdi_init,
+ parent,
+ x,
+ y,
+ width,
+ height);
+}
+
+#else
+
+EAPI Ecore_Evas *
+ecore_evas_software_gdi_new(Ecore_Win32_Window *parent __UNUSED__,
+ int x __UNUSED__,
+ int y __UNUSED__,
+ int width __UNUSED__,
+ int height __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_GDI */
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
+
+EAPI Ecore_Evas *
+ecore_evas_software_ddraw_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return _ecore_evas_win32_new_internal(_ecore_evas_engine_software_ddraw_init,
+ parent,
+ x,
+ y,
+ width,
+ height);
+}
+
+#else
+
+EAPI Ecore_Evas *
+ecore_evas_software_ddraw_new(Ecore_Win32_Window *parent __UNUSED__,
+ int x __UNUSED__,
+ int y __UNUSED__,
+ int width __UNUSED__,
+ int height __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_DDRAW */
+
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW
+
+EAPI Ecore_Evas *
+ecore_evas_software_16_ddraw_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return _ecore_evas_win32_new_internal(_ecore_evas_engine_software_16_ddraw_init,
+ parent,
+ x,
+ y,
+ width,
+ height);
+}
+
+#else
+
+EAPI Ecore_Evas *
+ecore_evas_software_16_ddraw_new(Ecore_Win32_Window *parent __UNUSED__,
+ int x __UNUSED__,
+ int y __UNUSED__,
+ int width __UNUSED__,
+ int height __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_DDRAW */
+
+
+#ifdef BUILD_ECORE_EVAS_DIRECT3D
+
+EAPI Ecore_Evas *
+ecore_evas_direct3d_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return _ecore_evas_win32_new_internal(_ecore_evas_engine_direct3d_init,
+ parent,
+ x,
+ y,
+ width,
+ height);
+}
+
+#else
+
+EAPI Ecore_Evas *
+ecore_evas_direct3d_new(Ecore_Win32_Window *parent __UNUSED__,
+ int x __UNUSED__,
+ int y __UNUSED__,
+ int width __UNUSED__,
+ int height __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* ! BUILD_ECORE_EVAS_DIRECT3D */
+
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_GLEW
+
+EAPI Ecore_Evas *
+ecore_evas_gl_glew_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return _ecore_evas_win32_new_internal(_ecore_evas_engine_opengl_glew_init,
+ parent,
+ x,
+ y,
+ width,
+ height);
+}
+
+#else
+
+EAPI Ecore_Evas *
+ecore_evas_gl_glew_new(Ecore_Win32_Window *parent __UNUSED__,
+ int x __UNUSED__,
+ int y __UNUSED__,
+ int width __UNUSED__,
+ int height __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* BUILD_ECORE_EVAS_OPENGL_GLEW */
+
+
+#ifdef BUILD_ECORE_EVAS_WIN32
+
+EAPI Ecore_Win32_Window *
+ecore_evas_win32_window_get(const Ecore_Evas *ee)
+{
+ return (Ecore_Win32_Window *) ecore_evas_window_get(ee);
+}
+
+#else
+
+EAPI Ecore_Win32_Window *
+ecore_evas_win32_window_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* BUILD_ECORE_EVAS_WIN32 */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h> /* for NULL */
+
+#include <Ecore.h>
+#include "ecore_private.h"
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+# include <Ecore_WinCE.h>
+# include <ecore_wince_private.h>
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_WINCE */
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+
+#define ECORE_EVAS_EVENT_COUNT 7
+
+static int _ecore_evas_init_count = 0;
+
+static Ecore_Event_Handler *ecore_evas_event_handlers[ECORE_EVAS_EVENT_COUNT];
+
+static int _ecore_evas_wince_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_wince_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_wince_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_wince_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_wince_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_wince_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static int _ecore_evas_wince_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+/* Private functions */
+
+static int
+_ecore_evas_wince_render(Ecore_Evas *ee)
+{
+ int rend = 0;
+ Eina_List *updates = NULL;
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ Eina_List *ll;
+ Ecore_Evas *ee2;
+
+ EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+ {
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ rend |= _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+ if (ee->prop.avoid_damage)
+ {
+ updates = evas_render_updates(ee->evas);
+ if (updates) evas_render_updates_free(updates);
+ }
+ else if ((ee->visible) ||
+ ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
+ ((ee->should_be_visible) && (ee->prop.override)))
+ {
+ if (ee->shaped)
+ {
+ updates = evas_render_updates(ee->evas);
+ if (updates) evas_render_updates_free(updates);
+ }
+ else
+ {
+ updates = evas_render_updates(ee->evas);
+ if (updates) evas_render_updates_free(updates);
+ }
+ }
+ else
+ evas_norender(ee->evas);
+ if (updates) rend = 1;
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+ return rend;
+}
+
+static int
+_ecore_evas_wince_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1)
+ return _ecore_evas_init_count;
+
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_WINCE_EVENT_MOUSE_IN, _ecore_evas_wince_event_mouse_in, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_WINCE_EVENT_MOUSE_OUT, _ecore_evas_wince_event_mouse_out, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_WINCE_EVENT_WINDOW_DAMAGE, _ecore_evas_wince_event_window_damage, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_WINCE_EVENT_WINDOW_DESTROY, _ecore_evas_wince_event_window_destroy, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_WINCE_EVENT_WINDOW_SHOW, _ecore_evas_wince_event_window_show, NULL);
+ ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_WINCE_EVENT_WINDOW_HIDE, _ecore_evas_wince_event_window_hide, NULL);
+ ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST, _ecore_evas_wince_event_window_delete_request, NULL);
+
+ ecore_event_evas_init();
+ return _ecore_evas_init_count;
+}
+
+int
+_ecore_evas_wince_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ int i;
+
+ for (i = 0; i < ECORE_EVAS_EVENT_COUNT; i++)
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ ecore_event_evas_shutdown();
+ }
+
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+
+ return _ecore_evas_init_count;
+}
+
+static int
+_ecore_evas_wince_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_WinCE_Event_Mouse_In *e;
+
+ INF("mouse in");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if (e->window != (Ecore_WinCE_Window *)ee->prop.window) return 1;
+
+ if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
+ /* FIXME to do */
+/* _ecore_evas_x_modifier_locks_update(ee, e->modifiers); */
+ evas_event_feed_mouse_in(ee->evas, e->time, NULL);
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+
+ return 1;
+}
+
+static int
+_ecore_evas_wince_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_WinCE_Event_Mouse_Out *e;
+
+ INF("mouse out");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if (e->window != (Ecore_WinCE_Window *)ee->prop.window) return 1;
+
+ /* FIXME to do */
+/* _ecore_evas_x_modifier_locks_update(ee, e->modifiers); */
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+
+ evas_event_feed_mouse_out(ee->evas, e->time, NULL);
+ if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
+ if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
+
+ return 1;
+}
+
+static int
+_ecore_evas_wince_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_WinCE_Event_Window_Damage *e;
+
+ INF("window damage");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if (e->window != (Ecore_WinCE_Window *)ee->prop.window) return 1;
+
+ if (ee->prop.avoid_damage)
+ {
+#warning [ECORE] [WINCE] No Region code
+ }
+ else
+ {
+ if (ee->rotation == 0)
+ evas_damage_rectangle_add(ee->evas,
+ e->x,
+ e->y,
+ e->width,
+ e->height);
+ else if (ee->rotation == 90)
+ evas_damage_rectangle_add(ee->evas,
+ ee->h - e->y - e->height,
+ e->x,
+ e->height,
+ e->width);
+ else if (ee->rotation == 180)
+ evas_damage_rectangle_add(ee->evas,
+ ee->w - e->x - e->width,
+ ee->h - e->y - e->height,
+ e->width,
+ e->height);
+ else if (ee->rotation == 270)
+ evas_damage_rectangle_add(ee->evas,
+ e->y,
+ ee->w - e->x - e->width,
+ e->height,
+ e->width);
+ }
+
+ return 1;
+}
+
+static int
+_ecore_evas_wince_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_WinCE_Event_Window_Destroy *e;
+
+ INF("window destroy");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if (e->window != (Ecore_WinCE_Window *)ee->prop.window) return 1;
+ if (ee->func.fn_destroy) ee->func.fn_destroy(ee);
+ ecore_evas_free(ee);
+
+ return 1;
+}
+
+static int
+_ecore_evas_wince_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_WinCE_Event_Window_Show *e;
+
+ INF("window show");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if (e->window != (Ecore_WinCE_Window *)ee->prop.window) return 1;
+ if (ee->visible) return 0; /* dont pass it on */
+ ee->visible = 1;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+
+ return 1;
+}
+
+static int
+_ecore_evas_wince_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_WinCE_Event_Window_Hide *e;
+
+ INF("window hide");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if (e->window != (Ecore_WinCE_Window *)ee->prop.window) return 1;
+ if (!ee->visible) return 0; /* dont pass it on */
+ ee->visible = 0;
+ if (ee->func.fn_hide) ee->func.fn_hide(ee);
+
+ return 1;
+}
+
+static int
+_ecore_evas_wince_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_WinCE_Event_Window_Delete_Request *e;
+
+ INF("window delete request");
+
+ e = event;
+ ee = ecore_event_window_match((Ecore_Window)e->window);
+ if (!ee) return 1; /* pass on event */
+ if (e->window != (Ecore_WinCE_Window *)ee->prop.window) return 1;
+ if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
+
+ return 1;
+}
+
+
+/* Ecore_Evas interface */
+
+static void
+_ecore_evas_wince_free(Ecore_Evas *ee)
+{
+ INF("ecore evas free");
+
+ ecore_wince_window_free((Ecore_WinCE_Window *)ee->prop.window);
+ ecore_event_window_unregister(ee->prop.window);
+ _ecore_evas_wince_shutdown();
+ ecore_wince_shutdown();
+}
+
+static void
+_ecore_evas_wince_callback_delete_request_set(Ecore_Evas *ee,
+ void (*func) (Ecore_Evas *ee))
+{
+ ee->func.fn_delete_request = func;
+}
+
+static void
+_ecore_evas_wince_move(Ecore_Evas *ee, int x, int y)
+{
+ INF("ecore evas move (%dx%d)", x, y);
+
+ if ((x != ee->x) || (y != ee->y))
+ {
+ ee->x = x;
+ ee->y = y;
+ ecore_wince_window_move((Ecore_WinCE_Window *)ee->prop.window, x, y);
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+}
+
+static void
+_ecore_evas_wince_resize(Ecore_Evas *ee, int width, int height)
+{
+ INF("ecore evas resize (%dx%d)", width, height);
+
+ if ((ee->w != width) || (ee->h != height))
+ {
+ ee->w = width;
+ ee->h = height;
+ ecore_wince_window_resize((Ecore_WinCE_Window *)ee->prop.window, width, height);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ /* FIXME: damage and shape */
+
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+}
+
+static void
+_ecore_evas_wince_move_resize(Ecore_Evas *ee, int x, int y, int width, int height)
+{
+ INF("ecore evas resize (%dx%d %dx%d)", x, y, width, height);
+
+ if ((ee->w != width) || (ee->h != height) || (x != ee->x) || (y != ee->y))
+ {
+ int change_size = 0;
+ int change_pos = 0;
+
+ if ((ee->w != width) || (ee->h != height)) change_size = 1;
+ if ((x != ee->x) || (y != ee->y)) change_pos = 1;
+
+ ee->x = x;
+ ee->y = y;
+ ee->w = width;
+ ee->h = height;
+ ecore_wince_window_move_resize((Ecore_WinCE_Window *)ee->prop.window, x, y, width, height);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ /* FIXME: damage and shape */
+ if (change_pos)
+ {
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+ if (change_size)
+ {
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ }
+}
+
+/* static void */
+/* _ecore_evas_wince_rotation_set(Ecore_Evas *ee, int rotation) */
+/* { */
+/* int rot_dif; */
+
+/* if (ee->rotation == rotation) return; */
+/* rot_dif = ee->rotation - rotation; */
+/* if (rot_dif < 0) rot_dif = -rot_dif; */
+/* if (!strcmp(ee->driver, "software_ddraw")) */
+/* { */
+/* Evas_Engine_Info_Software_16_WinCE *einfo; */
+
+/* einfo = (Evas_Engine_Info_Software_16_WinCE *)evas_engine_info_get(ee->evas); */
+/* if (!einfo) return; */
+/* if (rot_dif != 180) */
+/* { */
+/* int minw, minh, maxw, maxh, basew, baseh, stepw, steph; */
+
+/* einfo->info.rotation = rotation; */
+/* evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); */
+/* if (!ee->prop.fullscreen) */
+/* { */
+/* ecore_wince_window_resize(ee->prop.window, ee->h, ee->w); */
+/* ee->expecting_resize.w = ee->h; */
+/* ee->expecting_resize.h = ee->w; */
+/* } */
+/* else */
+/* { */
+/* int w, h; */
+
+/* ecore_wince_window_size_get(ee->prop.window, &w, &h); */
+/* ecore_wince_window_resize(ee->prop.window, h, w); */
+/* if ((rotation == 0) || (rotation == 180)) */
+/* { */
+/* evas_output_size_set(ee->evas, ee->w, ee->h); */
+/* evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); */
+/* } */
+/* else */
+/* { */
+/* evas_output_size_set(ee->evas, ee->h, ee->w); */
+/* evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); */
+/* } */
+/* if (ee->func.fn_resize) ee->func.fn_resize(ee); */
+/* } */
+/* ecore_evas_size_min_get(ee, &minw, &minh); */
+/* ecore_evas_size_max_get(ee, &maxw, &maxh); */
+/* ecore_evas_size_base_get(ee, &basew, &baseh); */
+/* ecore_evas_size_step_get(ee, &stepw, &steph); */
+/* ee->rotation = rotation; */
+/* ecore_evas_size_min_set(ee, minh, minw); */
+/* ecore_evas_size_max_set(ee, maxh, maxw); */
+/* ecore_evas_size_base_set(ee, baseh, basew); */
+/* ecore_evas_size_step_set(ee, steph, stepw); */
+/* _ecore_evas_wince_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, */
+/* ecore_wince_current_time_get()); */
+/* } */
+/* else */
+/* { */
+/* einfo->info.rotation = rotation; */
+/* evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); */
+/* ee->rotation = rotation; */
+/* _ecore_evas_wince_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, */
+/* ecore_wince_current_time_get()); */
+/* if (ee->func.fn_resize) ee->func.fn_resize(ee); */
+/* } */
+/* if ((ee->rotation == 90) || (ee->rotation == 270)) */
+/* evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); */
+/* else */
+/* evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); */
+/* } */
+/* } */
+
+static void
+_ecore_evas_wince_show(Ecore_Evas *ee)
+{
+ INF("ecore evas show");
+
+ ee->should_be_visible = 1;
+ if (ee->prop.avoid_damage)
+ _ecore_evas_wince_render(ee);
+ ecore_wince_window_show((Ecore_WinCE_Window *)ee->prop.window);
+/* if (ee->prop.fullscreen) */
+/* ecore_wince_window_focus(ee->prop.window); */
+}
+
+static void
+_ecore_evas_wince_hide(Ecore_Evas *ee)
+{
+ INF("ecore evas hide");
+
+ ecore_wince_window_hide((Ecore_WinCE_Window *)ee->prop.window);
+ ee->should_be_visible = 0;
+}
+
+/* static void */
+/* _ecore_evas_wince_raise(Ecore_Evas *ee) */
+/* { */
+/* if (!ee->prop.fullscreen) */
+/* ecore_wince_window_raise(ee->prop.window); */
+/* else */
+/* ecore_wince_window_raise(ee->prop.window); */
+/* } */
+
+/* static void */
+/* _ecore_evas_wince_lower(Ecore_Evas *ee) */
+/* { */
+/* if (!ee->prop.fullscreen) */
+/* ecore_wince_window_lower(ee->prop.window); */
+/* else */
+/* ecore_wince_window_lower(ee->prop.window); */
+/* } */
+
+static void
+_ecore_evas_wince_title_set(Ecore_Evas *ee, const char *title)
+{
+ INF("ecore evas title set");
+
+ if (ee->prop.title) free(ee->prop.title);
+ ee->prop.title = NULL;
+ if (title) ee->prop.title = strdup(title);
+ ecore_wince_window_title_set((Ecore_WinCE_Window *)ee->prop.window, ee->prop.title);
+}
+
+/* static void */
+/* _ecore_evas_wince_size_min_set(Ecore_Evas *ee, int width, int height) */
+/* { */
+/* if (width < 0) width = 0; */
+/* if (height < 0) height = 0; */
+/* if ((ee->prop.min.w == width) && (ee->prop.min.h == height)) return; */
+/* ee->prop.min.w = width; */
+/* ee->prop.min.h = height; */
+/* ecore_wince_window_size_min_set(ee->prop.window, width, height); */
+/* } */
+
+/* static void */
+/* _ecore_evas_wince_size_max_set(Ecore_Evas *ee, int width, int height) */
+/* { */
+/* if (width < 0) width = 0; */
+/* if (height < 0) height = 0; */
+/* if ((ee->prop.max.w == width) && (ee->prop.max.h == height)) return; */
+/* ee->prop.max.w = width; */
+/* ee->prop.max.h = height; */
+/* ecore_wince_window_size_max_set(ee->prop.window, width, height); */
+/* } */
+
+/* static void */
+/* _ecore_evas_wince_size_base_set(Ecore_Evas *ee, int width, int height) */
+/* { */
+/* if (width < 0) width = 0; */
+/* if (height < 0) height = 0; */
+/* if ((ee->prop.base.w == width) && (ee->prop.base.h == height)) return; */
+/* ee->prop.base.w = width; */
+/* ee->prop.base.h = height; */
+/* ecore_wince_window_size_base_set(ee->prop.window, width, height); */
+/* } */
+
+/* static void */
+/* _ecore_evas_wince_size_step_set(Ecore_Evas *ee, int width, int height) */
+/* { */
+/* if (width < 1) width = 1; */
+/* if (height < 1) height = 1; */
+/* if ((ee->prop.step.w == width) && (ee->prop.step.h == height)) return; */
+/* ee->prop.step.w = width; */
+/* ee->prop.step.h = height; */
+/* ecore_wince_window_size_step_set(ee->prop.window, width, height); */
+/* } */
+
+static void
+_ecore_evas_wince_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+#if 0
+ int x, y;
+
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+ if (obj == NULL)
+ {
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ ecore_wince_window_cursor_show(ee->prop.window, 1);
+ return;
+ }
+
+ ee->prop.cursor.object = obj;
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+
+ ecore_wince_window_cursor_show(ee->prop.window, 0);
+
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+#endif
+}
+
+/* static void */
+/* _ecore_evas_wince_focus_set(Ecore_Evas *ee, int on __UNUSED__) */
+/* { */
+/* ecore_wince_window_focus_set(ee->prop.window); */
+/* } */
+
+/* static void */
+/* _ecore_evas_wince_iconified_set(Ecore_Evas *ee, int on) */
+/* { */
+/* /\* if (((ee->prop.borderless) && (on)) || *\/ */
+/* /\* ((!ee->prop.borderless) && (!on))) return; *\/ */
+/* ee->prop.iconified = on; */
+/* ecore_wince_window_iconified_set(ee->prop.window, ee->prop.iconified); */
+/* } */
+
+/* static void */
+/* _ecore_evas_wince_borderless_set(Ecore_Evas *ee, int on) */
+/* { */
+/* if (((ee->prop.borderless) && (on)) || */
+/* ((!ee->prop.borderless) && (!on))) return; */
+/* ee->prop.borderless = on; */
+/* ecore_wince_window_borderless_set(ee->prop.window, ee->prop.borderless); */
+/* } */
+
+static void
+_ecore_evas_wince_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ Evas_Engine_Info_Software_16_WinCE *einfo;
+ struct _Ecore_WinCE_Window *window;
+
+ INF("ecore evas fullscreen set");
+
+ if ((ee->engine.wince.state.fullscreen && on) ||
+ (!ee->engine.wince.state.fullscreen && !on))
+ return;
+
+ ee->engine.wince.state.fullscreen = on;
+ ee->prop.fullscreen = on;
+
+ window = (struct _Ecore_WinCE_Window *)ee->prop.window;
+
+ if (on != 0)
+ {
+/* ecore_win32_window_shape_set(ee->engine.win32.window, 0, 0, NULL); */
+ ecore_wince_window_fullscreen_set((Ecore_WinCE_Window *)ee->prop.window, on);
+ ee->w = GetSystemMetrics(SM_CXSCREEN);
+ ee->h = GetSystemMetrics(SM_CYSCREEN);
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ int w;
+ int h;
+
+ ecore_wince_window_fullscreen_set((Ecore_WinCE_Window *)ee->prop.window, on);
+ ecore_wince_window_size_get((Ecore_WinCE_Window *)ee->prop.window, &w, &h);
+ ee->w = w;
+ ee->h = h;
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+/* ecore_win32_window_shape_set(window, */
+/* window->shape.width, */
+/* window->shape.height, */
+/* window->shape.mask); */
+ }
+
+ einfo = (Evas_Engine_Info_Software_16_WinCE *)evas_engine_info_get(ecore_evas_get(ee));
+ if (einfo != NULL)
+ {
+ einfo->info.fullscreen = !!on;
+/* einfo->info.layered = window->shape.layered; */
+ evas_engine_info_set(ecore_evas_get(ee), (Evas_Engine_Info *)einfo);
+ }
+}
+
+static Ecore_Evas_Engine_Func _ecore_wince_engine_func =
+{
+ _ecore_evas_wince_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_wince_callback_delete_request_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_wince_move,
+ NULL,
+ _ecore_evas_wince_resize,
+ _ecore_evas_wince_move_resize,
+ NULL, //_ecore_evas_wince_rotation_set,
+ NULL, /* _ecore_evas_x_shaped_set */
+ _ecore_evas_wince_show,
+ _ecore_evas_wince_hide,
+ NULL, //_ecore_evas_wince_raise,
+ NULL, //_ecore_evas_wince_lower,
+ NULL, //_ecore_evas_wince_activate,
+ _ecore_evas_wince_title_set,
+ NULL, /* _ecore_evas_x_name_class_set */
+ NULL, //_ecore_evas_wince_size_min_set,
+ NULL, //_ecore_evas_wince_size_max_set,
+ NULL, //_ecore_evas_wince_size_base_set,
+ NULL, //_ecore_evas_wince_size_step_set,
+ _ecore_evas_wince_cursor_set,
+ NULL, /* _ecore_evas_x_layer_set */
+ NULL, //_ecore_evas_wince_focus_set,
+ NULL, //_ecore_evas_wince_iconified_set,
+ NULL, //_ecore_evas_wince_borderless_set,
+ NULL, /* _ecore_evas_x_override_set */
+ NULL,
+ _ecore_evas_wince_fullscreen_set,
+ NULL, /* _ecore_evas_x_avoid_damage_set */
+ NULL, /* _ecore_evas_x_withdrawn_set */
+ NULL, /* _ecore_evas_x_sticky_set */
+ NULL, /* _ecore_evas_x_ignore_events_set */
+ NULL, /* _ecore_evas_x_alpha_set */
+ NULL, //transparent
+
+ NULL // render
+};
+
+/* API */
+
+static Ecore_Evas *
+ecore_evas_software_wince_new_internal(int backend,
+ Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ int fullscreen)
+{
+ Evas_Engine_Info_Software_16_WinCE *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("software_16_wince");
+ if (!rmethod)
+ return NULL;
+
+ if (!ecore_wince_init())
+ return NULL;
+
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee)
+ {
+ ecore_wince_shutdown();
+ return NULL;
+ }
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ if (!_ecore_evas_wince_init())
+ {
+ free(ee);
+ ecore_wince_shutdown();
+ return NULL;
+ }
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wince_engine_func;
+
+ ee->driver = "software_16_wince";
+
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = width;
+ ee->h = height;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+ ee->prop.request_pos = 0;
+ ee->prop.sticky = 0;
+ /* FIXME: sticky to add */
+
+ ee->prop.window = (Ecore_Window)ecore_wince_window_new((Ecore_WinCE_Window *)parent, x, y, width, height);
+ if (!ee->prop.window)
+ {
+ _ecore_evas_wince_shutdown();
+ free(ee);
+ ecore_wince_shutdown();
+ return NULL;
+ }
+
+ ecore_wince_window_fullscreen_set((Ecore_WinCE_Window *)ee->prop.window, fullscreen);
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, width, height);
+ evas_output_viewport_set(ee->evas, 0, 0, width, height);
+
+ einfo = (Evas_Engine_Info_Software_16_WinCE *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ /* FIXME: REDRAW_DEBUG missing for now */
+ einfo->info.window = ((struct _Ecore_WinCE_Window *)ee->prop.window)->window;
+ einfo->info.width = width;
+ einfo->info.height = height;
+ einfo->info.backend = backend;
+ einfo->info.rotation = 0;
+ einfo->info.fullscreen = fullscreen;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+
+ ecore_wince_window_backend_set((Ecore_WinCE_Window *)ee->prop.window, backend);
+ ecore_wince_window_suspend_set((Ecore_WinCE_Window *)ee->prop.window, einfo->func.suspend);
+ ecore_wince_window_resume_set((Ecore_WinCE_Window *)ee->prop.window, einfo->func.resume);
+ }
+
+ ee->engine.func->fn_render = _ecore_evas_wince_render;
+ _ecore_evas_register(ee);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process);
+ evas_focus_in(ee->evas);
+
+ return ee;
+}
+
+#else
+
+static Ecore_Evas *
+ecore_evas_software_wince_new_internal(int backend __UNUSED__,
+ Ecore_WinCE_Window *parent __UNUSED__,
+ int x __UNUSED__,
+ int y __UNUSED__,
+ int width __UNUSED__,
+ int height __UNUSED__,
+ int fullscreen __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_WINCE */
+
+
+EAPI Ecore_Evas *
+ecore_evas_software_wince_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return ecore_evas_software_wince_new_internal(0, parent, x, y, width, height, 1);
+}
+
+EAPI Ecore_Evas *
+ecore_evas_software_wince_fb_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return ecore_evas_software_wince_new_internal(1, parent, x, y, width, height, 1);
+}
+
+EAPI Ecore_Evas *
+ecore_evas_software_wince_gapi_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return ecore_evas_software_wince_new_internal(2, parent, x, y, width, height, 1);
+}
+
+EAPI Ecore_Evas *
+ecore_evas_software_wince_ddraw_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return ecore_evas_software_wince_new_internal(3, parent, x, y, width, height, 1);
+}
+
+EAPI Ecore_Evas *
+ecore_evas_software_wince_gdi_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ return ecore_evas_software_wince_new_internal(4, parent, x, y, width, height, 0);
+}
+
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
+
+EAPI Ecore_WinCE_Window *
+ecore_evas_software_wince_window_get(const Ecore_Evas *ee)
+{
+ return (Ecore_WinCE_Window *) ecore_evas_window_get(ee);
+}
+
+#else
+
+EAPI Ecore_WinCE_Window *
+ecore_evas_software_wince_window_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return NULL;
+}
+
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_WINCE */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <Ecore.h>
+#include <Ecore_Input.h>
+#include <Ecore_Input_Evas.h>
+#ifdef BUILD_ECORE_EVAS_X11
+# include <Ecore_X.h>
+# include <Ecore_X_Atoms.h>
+#endif
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_X11
+static int _ecore_evas_init_count = 0;
+
+static Ecore_Event_Handler *ecore_evas_event_handlers[13];
+
+static void
+_ecore_evas_x_protocols_set(Ecore_Evas *ee)
+{
+ Ecore_X_Atom protos[10];
+ int num = 0;
+
+ if (ee->func.fn_delete_request)
+ protos[num++] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ protos[num++] = ECORE_X_ATOM_NET_WM_PING;
+ ecore_x_icccm_protocol_atoms_set(ee->prop.window, protos, num);
+}
+
+static void
+_ecore_evas_x_sync_set(Ecore_Evas *ee)
+{
+ if ((ecore_x_e_comp_sync_supported_get(ee->engine.x.win_root)) &&
+ (!ee->no_comp_sync) && (_ecore_evas_app_comp_sync))
+ {
+ if (!ee->engine.x.sync_counter)
+ ee->engine.x.sync_counter = ecore_x_sync_counter_new(0);
+ }
+ else
+ {
+ if (ee->engine.x.sync_counter)
+ ecore_x_sync_counter_free(ee->engine.x.sync_counter);
+ ee->engine.x.sync_counter = 0;
+ }
+ ecore_x_e_comp_sync_counter_set(ee->prop.window, ee->engine.x.sync_counter);
+}
+
+static void
+_ecore_evas_x_sync_clear(Ecore_Evas *ee)
+{
+ if (!ee->engine.x.sync_counter) return;
+ ecore_x_sync_counter_free(ee->engine.x.sync_counter);
+ ee->engine.x.sync_counter = 0;
+}
+
+#ifdef HAVE_ECORE_X_XCB
+static xcb_visualtype_t *
+xcb_visualtype_get(xcb_screen_t *screen, xcb_visualid_t visual)
+{
+ xcb_depth_iterator_t iter_depth;
+
+ if (!screen) return NULL;
+
+ iter_depth = xcb_screen_allowed_depths_iterator(screen);
+ for (; iter_depth.rem; xcb_depth_next (&iter_depth))
+ {
+ xcb_visualtype_iterator_t iter_vis;
+
+ iter_vis = xcb_depth_visuals_iterator(iter_depth.data);
+ for (; iter_vis.rem; --screen, xcb_visualtype_next (&iter_vis))
+ {
+ if (visual == iter_vis.data->visual_id)
+ return iter_vis.data;
+ }
+ }
+
+ return NULL;
+}
+#endif /* HAVE_ECORE_X_XCB */
+
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+# ifdef HAVE_ECORE_X_XCB
+/* noop */
+# else
+static Ecore_X_Window
+_ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y, int w, int h, int override, int argb, const int *opt)
+{
+ Evas_Engine_Info_GL_X11 *einfo;
+ Ecore_X_Window win;
+
+ einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ XSetWindowAttributes attr;
+ int screen;
+
+ if (opt)
+ {
+ int op;
+
+ for (op = 0; opt[op]; op++)
+ {
+ if (opt[op] == ECORE_EVAS_GL_X11_OPT_INDIRECT)
+ {
+ op++;
+ einfo->indirect = opt[op];
+ }
+ }
+ }
+
+ /* FIXME: this is inefficient as its 1 or more round trips */
+ screen = DefaultScreen(ecore_x_display_get());
+ if (ScreenCount(ecore_x_display_get()) > 1)
+ {
+ Ecore_X_Window *roots;
+ int num, i;
+
+ num = 0;
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ XWindowAttributes at;
+
+ if (XGetWindowAttributes(ecore_x_display_get(),
+ parent, &at))
+ {
+ for (i = 0; i < num; i++)
+ {
+ if (at.root == roots[i])
+ {
+ screen = i;
+ break;
+ }
+ }
+ }
+ free(roots);
+ }
+ }
+ einfo->info.display = ecore_x_display_get();
+ einfo->info.screen = screen;
+
+ einfo->info.destination_alpha = argb;
+
+ einfo->info.visual = einfo->func.best_visual_get(einfo);
+ einfo->info.colormap = einfo->func.best_colormap_get(einfo);
+ einfo->info.depth = einfo->func.best_depth_get(einfo);
+
+
+ if ((!einfo->info.visual) ||
+ (!einfo->info.colormap) ||
+ (!einfo->info.depth))
+ {
+ WRN("OpenGL X11 init engine '%s' failed - no visual, colormap or depth.", ee->driver);
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ return 0;
+ }
+
+ attr.backing_store = NotUseful;
+ attr.override_redirect = override;
+ attr.colormap = einfo->info.colormap;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.event_mask =
+ KeyPressMask | KeyReleaseMask |
+ ExposureMask | ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask |
+ PointerMotionMask | StructureNotifyMask | VisibilityChangeMask |
+ FocusChangeMask | PropertyChangeMask | ColormapChangeMask;
+ attr.bit_gravity = ForgetGravity;
+
+ win =
+ XCreateWindow(einfo->info.display, parent, x, y, w, h, 0,
+ einfo->info.depth, InputOutput, einfo->info.visual,
+ CWBackingStore | CWColormap | CWBackPixmap |
+ CWBorderPixel | CWBitGravity | CWEventMask |
+ CWOverrideRedirect, &attr);
+ einfo->info.drawable = win;
+
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
+ XDestroyWindow(einfo->info.display, win);
+ return 0;
+ }
+ ecore_x_window_defaults_set(win);
+ _ecore_evas_x_protocols_set(ee);
+ _ecore_evas_x_sync_set(ee);
+ }
+ else
+ {
+ win = 0;
+ }
+ return win;
+}
+#endif /* HAVE_ECORE_X_XCB */
+#endif
+
+static int
+_ecore_evas_x_render(Ecore_Evas *ee)
+{
+ Eina_Rectangle *r;
+ Eina_List *updates, *l;
+ int rend = 0;
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+ Eina_List *ll;
+ Ecore_Evas *ee2;
+
+ if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) &&
+ (ee->engine.x.sync_counter) && (!ee->engine.x.sync_began) &&
+ (!ee->engine.x.sync_cancel))
+ return 0;
+
+ EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+ {
+ if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+ rend |= _ecore_evas_buffer_render(ee2);
+ if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+ }
+#endif
+ if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+ if (ee->prop.avoid_damage)
+ {
+ updates = evas_render_updates(ee->evas);
+ if (ee->engine.x.using_bg_pixmap)
+ {
+ if (updates)
+ {
+ EINA_LIST_FOREACH(updates, l, r)
+ ecore_x_window_area_clear(ee->prop.window, r->x, r->y, r->w, r->h);
+ if ((ee->shaped) && (updates))
+ ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask);
+// if ((ee->alpha) && (updates))
+// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
+ evas_render_updates_free(updates);
+ _ecore_evas_idle_timeout_update(ee);
+ rend = 1;
+ }
+ }
+ else
+ {
+ EINA_LIST_FOREACH(updates, l, r)
+ {
+ Ecore_X_Rectangle rect;
+ Ecore_X_XRegion *tmpr;
+
+ if (!ee->engine.x.damages)
+ ee->engine.x.damages = ecore_x_xregion_new();
+ tmpr = ecore_x_xregion_new();
+ if (ee->rotation == 0)
+ {
+ rect.x = r->x;
+ rect.y = r->y;
+ rect.width = r->w;
+ rect.height = r->h;
+ }
+ else if (ee->rotation == 90)
+ {
+ rect.x = r->y;
+ rect.y = ee->h - r->x - r->w;
+ rect.width = r->h;
+ rect.height = r->w;
+ }
+ else if (ee->rotation == 180)
+ {
+ rect.x = ee->w - r->x - r->w;
+ rect.y = ee->h - r->y - r->h;
+ rect.width = r->w;
+ rect.height = r->h;
+ }
+ else if (ee->rotation == 270)
+ {
+ rect.x = ee->w - r->y - r->h;
+ rect.y = r->x;
+ rect.width = r->h;
+ rect.height = r->w;
+ }
+ ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect);
+ ecore_x_xregion_free(ee->engine.x.damages);
+ ee->engine.x.damages = tmpr;
+ }
+ if (ee->engine.x.damages)
+ {
+ /* if we have a damage pixmap - we can avoid exposures by
+ * disabling them just for setting the mask */
+ ecore_x_event_mask_set(ee->prop.window,
+ ECORE_X_EVENT_MASK_KEY_DOWN |
+ ECORE_X_EVENT_MASK_KEY_UP |
+ ECORE_X_EVENT_MASK_MOUSE_DOWN |
+ ECORE_X_EVENT_MASK_MOUSE_UP |
+ ECORE_X_EVENT_MASK_MOUSE_IN |
+ ECORE_X_EVENT_MASK_MOUSE_OUT |
+ ECORE_X_EVENT_MASK_MOUSE_MOVE |
+// ECORE_X_EVENT_MASK_WINDOW_DAMAGE |
+ ECORE_X_EVENT_MASK_WINDOW_VISIBILITY |
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE |
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE |
+ ECORE_X_EVENT_MASK_WINDOW_PROPERTY |
+ ECORE_X_EVENT_MASK_WINDOW_COLORMAP
+ );
+ if ((ee->shaped) && (updates))
+ ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask);
+ /* and re-enable them again */
+ ecore_x_event_mask_set(ee->prop.window,
+ ECORE_X_EVENT_MASK_KEY_DOWN |
+ ECORE_X_EVENT_MASK_KEY_UP |
+ ECORE_X_EVENT_MASK_MOUSE_DOWN |
+ ECORE_X_EVENT_MASK_MOUSE_UP |
+ ECORE_X_EVENT_MASK_MOUSE_IN |
+ ECORE_X_EVENT_MASK_MOUSE_OUT |
+ ECORE_X_EVENT_MASK_MOUSE_MOVE |
+ ECORE_X_EVENT_MASK_WINDOW_DAMAGE |
+ ECORE_X_EVENT_MASK_WINDOW_VISIBILITY |
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE |
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE |
+ ECORE_X_EVENT_MASK_WINDOW_PROPERTY |
+ ECORE_X_EVENT_MASK_WINDOW_COLORMAP
+ );
+ ecore_x_xregion_set(ee->engine.x.damages, ee->engine.x.gc);
+ /* debug rendering */
+ /*
+ XSetForeground(ecore_x_display_get(), ee->engine.x.gc, rand());
+ XFillRectangle(ecore_x_display_get(), ee->prop.window, ee->engine.x.gc,
+ 0, 0, ee->w, ee->h);
+ XSync(ecore_x_display_get(), False);
+ usleep(20000);
+ XSync(ecore_x_display_get(), False);
+ */
+ ecore_x_pixmap_paste(ee->engine.x.pmap, ee->prop.window, ee->engine.x.gc,
+ 0, 0, ee->w, ee->h, 0, 0);
+ ecore_x_xregion_free(ee->engine.x.damages);
+ ee->engine.x.damages = NULL;
+ }
+ if (updates)
+ {
+ evas_render_updates_free(updates);
+ _ecore_evas_idle_timeout_update(ee);
+ rend = 1;
+ }
+ }
+ }
+ else if (((ee->visible) && (ee->draw_ok)) ||
+ ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
+ ((ee->should_be_visible) && (ee->prop.override)))
+ {
+
+ updates = evas_render_updates(ee->evas);
+ if (updates)
+ {
+ if (ee->shaped)
+ ecore_x_window_shape_mask_set(ee->prop.window, ee->engine.x.mask);
+// if (ee->alpha)
+// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
+ evas_render_updates_free(updates);
+ _ecore_evas_idle_timeout_update(ee);
+ rend = 1;
+ }
+ }
+ else
+ evas_norender(ee->evas);
+ if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+/*
+ if (rend)
+ {
+ static int frames = 0;
+ static double t0 = 0.0;
+ double t, td;
+
+ t = ecore_time_get();
+ frames++;
+ if ((t - t0) > 1.0)
+ {
+ td = t - t0;
+ printf("FPS: %3.3f\n", (double)frames / td);
+ frames = 0;
+ t0 = t;
+ }
+ }
+ */
+ return rend;
+}
+
+static void
+_ecore_evas_x_resize_shape(Ecore_Evas *ee)
+{
+ if (!strcmp(ee->driver, "software_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ unsigned int foreground;
+ Ecore_X_GC gc;
+
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
+ foreground = 0;
+ gc = ecore_x_gc_new(ee->engine.x.mask,
+ ECORE_X_GC_VALUE_MASK_FOREGROUND,
+ &foreground);
+ ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
+ 0, 0, ee->w, ee->h);
+ ecore_x_gc_free(gc);
+ einfo->info.mask = ee->engine.x.mask;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
+ }
+ else if (!strcmp(ee->driver, "xrender_x11"))
+ {
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+ Evas_Engine_Info_XRender_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ unsigned int foreground;
+ Ecore_X_GC gc;
+
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
+ foreground = 0;
+ gc = ecore_x_gc_new(ee->engine.x.mask,
+ ECORE_X_GC_VALUE_MASK_FOREGROUND,
+ &foreground);
+ ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
+ 0, 0, ee->w, ee->h);
+ ecore_x_gc_free(gc);
+ einfo->info.mask = ee->engine.x.mask;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+
+ }
+#endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
+ }
+ else if (!strcmp(ee->driver, "software_16_x11"))
+ {
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+# if 0 /* XXX no shaped window support for software_16_x11 */
+ Evas_Engine_Info_Software_16_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
+ einfo->info.mask = ee->engine.x.mask;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+# endif /* XXX no shaped window support for software_16_x11 */
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+ }
+}
+
+/* TODO: we need to make this work for all the states, not just sticky */
+static int
+_ecore_evas_x_event_property_change(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Property *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
+ {
+ unsigned int i, num;
+ Ecore_X_Window_State *state;
+ int sticky;
+
+#ifdef HAVE_ECORE_X_XCB
+ ecore_x_netwm_window_state_get_prefetch(e->win);
+#endif /* HAVE_ECORE_X_XCB */
+ sticky = 0;
+
+ /* TODO: we need to move those to the end, with if statements */
+ ee->engine.x.state.modal = 0;
+ ee->engine.x.state.maximized_v = 0;
+ ee->engine.x.state.maximized_h = 0;
+ ee->engine.x.state.shaded = 0;
+ ee->engine.x.state.skip_taskbar = 0;
+ ee->engine.x.state.skip_pager = 0;
+ ee->prop.fullscreen = 0;
+ ee->engine.x.state.fullscreen = 0;
+ ee->engine.x.state.above = 0;
+ ee->engine.x.state.below = 0;
+
+#ifdef HAVE_ECORE_X_XCB
+ ecore_x_netwm_window_state_get_fetch();
+#endif /* HAVE_ECORE_X_XCB */
+ ecore_x_netwm_window_state_get(e->win, &state, &num);
+ if (state)
+ {
+ for (i = 0; i < num; i++)
+ {
+ switch (state[i])
+ {
+ case ECORE_X_WINDOW_STATE_MODAL:
+ ee->engine.x.state.modal = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_STICKY:
+ if (ee->prop.sticky && ee->engine.x.state.sticky)
+ break;
+
+ sticky = 1;
+ ee->prop.sticky = 1;
+ ee->engine.x.state.sticky = 1;
+ if (ee->func.fn_sticky) ee->func.fn_sticky(ee);
+ break;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
+ ee->engine.x.state.maximized_v = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
+ ee->engine.x.state.maximized_h = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_SHADED:
+ ee->engine.x.state.shaded = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
+ ee->engine.x.state.skip_taskbar = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_SKIP_PAGER:
+ ee->engine.x.state.skip_pager = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_FULLSCREEN:
+ ee->prop.fullscreen = 1;
+ ee->engine.x.state.fullscreen = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_ABOVE:
+ ee->engine.x.state.above = 1;
+ break;
+ case ECORE_X_WINDOW_STATE_BELOW:
+ ee->engine.x.state.below = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ free(state);
+ }
+#ifdef HAVE_ECORE_X_XCB
+ ecore_xcb_reply_free();
+#endif /* HAVE_ECORE_X_XCB */
+
+ if (ee->prop.sticky && !sticky)
+ {
+ ee->prop.sticky = 0;
+ ee->engine.x.state.sticky = 0;
+ if (ee->func.fn_unsticky) ee->func.fn_unsticky(ee);
+ }
+ }
+
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_visibility_change(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Visibility_Change *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+// printf("VIS CHANGE OBSCURED: %p %i\n", ee, e->fully_obscured);
+ if (e->fully_obscured)
+ {
+ /* FIXME: round trip */
+ if (!ecore_x_screen_is_composited(ee->engine.x.screen_num))
+ ee->draw_ok = 0;
+ }
+ else ee->draw_ok = 1;
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_client_message(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Client_Message *e;
+
+ e = event;
+ if (e->format != 32) return 1;
+ if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_BEGIN)
+ {
+ ee = ecore_event_window_match(e->data.l[0]);
+ if (!ee) return 1; /* pass on event */
+ if (e->data.l[0] != (long)ee->prop.window) return 1;
+ ee->engine.x.sync_began = 1;
+ ee->engine.x.sync_cancel = 0;
+ }
+ else if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_END)
+ {
+ ee = ecore_event_window_match(e->data.l[0]);
+ if (!ee) return 1; /* pass on event */
+ if (e->data.l[0] != (long)ee->prop.window) return 1;
+ ee->engine.x.sync_began = 0;
+ ee->engine.x.sync_cancel = 0;
+ }
+ else if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_CANCEL)
+ {
+ ee = ecore_event_window_match(e->data.l[0]);
+ if (!ee) return 1; /* pass on event */
+ if (e->data.l[0] != (long)ee->prop.window) return 1;
+ ee->engine.x.sync_began = 0;
+ ee->engine.x.sync_cancel = 1;
+ }
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_In *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+/* { */
+/* time_t t; */
+/* char *ct; */
+
+/* const char *modes[] = { */
+/* "MODE_NORMAL", */
+/* "MODE_WHILE_GRABBED", */
+/* "MODE_GRAB", */
+/* "MODE_UNGRAB" */
+/* }; */
+/* const char *details[] = { */
+/* "DETAIL_ANCESTOR", */
+/* "DETAIL_VIRTUAL", */
+/* "DETAIL_INFERIOR", */
+/* "DETAIL_NON_LINEAR", */
+/* "DETAIL_NON_LINEAR_VIRTUAL", */
+/* "DETAIL_POINTER", */
+/* "DETAIL_POINTER_ROOT", */
+/* "DETAIL_DETAIL_NONE" */
+/* }; */
+/* t = time(NULL); */
+/* ct = ctime(&t); */
+/* ct[strlen(ct) - 1] = 0; */
+/* printf("@@ ->IN 0x%x 0x%x %s md=%s dt=%s\n", */
+/* e->win, e->event_win, */
+/* ct, */
+/* modes[e->mode], */
+/* details[e->detail]); */
+/* } */
+ // disable. causes mroe problems than it fixes
+ // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) ||
+ // (e->mode == ECORE_X_EVENT_MODE_UNGRAB))
+ // return 0;
+ /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
+ if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
+ ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers);
+ evas_event_feed_mouse_in(ee->evas, e->time, NULL);
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Mouse_Out *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if ((!ee) || (ee->ignore_events)) return 1;
+ /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+/* { */
+/* time_t t; */
+/* char *ct; */
+
+/* const char *modes[] = { */
+/* "MODE_NORMAL", */
+/* "MODE_WHILE_GRABBED", */
+/* "MODE_GRAB", */
+/* "MODE_UNGRAB" */
+/* }; */
+/* const char *details[] = { */
+/* "DETAIL_ANCESTOR", */
+/* "DETAIL_VIRTUAL", */
+/* "DETAIL_INFERIOR", */
+/* "DETAIL_NON_LINEAR", */
+/* "DETAIL_NON_LINEAR_VIRTUAL", */
+/* "DETAIL_POINTER", */
+/* "DETAIL_POINTER_ROOT", */
+/* "DETAIL_DETAIL_NONE" */
+/* }; */
+/* t = time(NULL); */
+/* ct = ctime(&t); */
+/* ct[strlen(ct) - 1] = 0; */
+/* printf("@@ ->OUT 0x%x 0x%x %s md=%s dt=%s\n", */
+/* e->win, e->event_win, */
+/* ct, */
+/* modes[e->mode], */
+/* details[e->detail]); */
+/* } */
+ // disable. causes more problems than it fixes
+ // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) ||
+ // (e->mode == ECORE_X_EVENT_MODE_UNGRAB))
+ // return 0;
+ /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
+ ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers);
+ _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
+ if (e->mode == ECORE_X_EVENT_MODE_GRAB)
+ evas_event_feed_mouse_cancel(ee->evas, e->time, NULL);
+ evas_event_feed_mouse_out(ee->evas, e->time, NULL);
+ if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
+ if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Focus_In *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) return 1;
+ ee->prop.focused = 1;
+ evas_focus_in(ee->evas);
+ if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Focus_Out *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if ((!ee) || (ee->ignore_events)) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (e->mode == ECORE_X_EVENT_MODE_GRAB) return 1;
+// if (ee->prop.fullscreen)
+// ecore_x_window_focus(ee->prop.window);
+ evas_focus_out(ee->evas);
+ ee->prop.focused = 0;
+ if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Damage *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (ee->engine.x.using_bg_pixmap) return 1;
+// printf("EXPOSE %p [%i] %i %i %ix%i\n", ee, ee->prop.avoid_damage, e->x, e->y, e->w, e->h);
+ if (ee->prop.avoid_damage)
+ {
+ Ecore_X_Rectangle rect;
+ Ecore_X_XRegion *tmpr;
+
+ if (!ee->engine.x.damages) ee->engine.x.damages = ecore_x_xregion_new();
+ tmpr = ecore_x_xregion_new();
+ rect.x = e->x;
+ rect.y = e->y;
+ rect.width = e->w;
+ rect.height = e->h;
+ ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect);
+ ecore_x_xregion_free(ee->engine.x.damages);
+ ee->engine.x.damages = tmpr;
+/* no - this breaks things badly. disable. Ecore_X_Rectangle != XRectangle - see
+ * the typedefs in x's headers and ecore_x's. also same with Region - it's a pointer in x - not an X ID
+ Ecore_X_Rectangle rect;
+ Ecore_X_XRegion *tmpr;
+
+ if (!ee->engine.x.damages) ee->engine.x.damages = ecore_x_xregion_new();
+ tmpr = ecore_x_xregion_new();
+ rect.x = e->x;
+ rect.y = e->y;
+ rect.width = e->w;
+ rect.height = e->h;
+ ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect);
+ ecore_x_xregion_free(ee->engine.x.damages);
+ ee->engine.x.damages = tmpr;
+ */
+ }
+ else
+ {
+ if (ee->rotation == 0)
+ evas_damage_rectangle_add(ee->evas,
+ e->x,
+ e->y,
+ e->w, e->h);
+ else if (ee->rotation == 90)
+ evas_damage_rectangle_add(ee->evas,
+ ee->h - e->y - e->h,
+ e->x,
+ e->h, e->w);
+ else if (ee->rotation == 180)
+ evas_damage_rectangle_add(ee->evas,
+ ee->w - e->x - e->w,
+ ee->h - e->y - e->h,
+ e->w, e->h);
+ else if (ee->rotation == 270)
+ evas_damage_rectangle_add(ee->evas,
+ e->y,
+ ee->w - e->x - e->w,
+ e->h, e->w);
+ }
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Destroy *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (ee->func.fn_destroy) ee->func.fn_destroy(ee);
+ _ecore_evas_x_sync_clear(ee);
+ ecore_evas_free(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Configure *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (ee->engine.x.direct_resize) return 1;
+
+ if ((e->from_wm) || (ee->prop.override))
+ {
+ if ((ee->x != e->x) || (ee->y != e->y))
+ {
+ ee->x = e->x;
+ ee->y = e->y;
+ ee->req.x = ee->x;
+ ee->req.y = ee->y;
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+ }
+ if ((ee->w != e->w) || (ee->h != e->h))
+ {
+ ee->w = e->w;
+ ee->h = e->h;
+ ee->req.w = ee->w;
+ ee->req.h = ee->h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ int pdam;
+
+ pdam = ecore_evas_avoid_damage_get(ee);
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, pdam);
+ }
+ if ((ee->shaped) || (ee->alpha))
+ _ecore_evas_x_resize_shape(ee);
+ if ((ee->expecting_resize.w > 0) &&
+ (ee->expecting_resize.h > 0))
+ {
+ if ((ee->expecting_resize.w == ee->w) &&
+ (ee->expecting_resize.h == ee->h))
+ _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_x_current_time_get());
+ ee->expecting_resize.w = 0;
+ ee->expecting_resize.h = 0;
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Delete_Request *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Show *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (ee->visible) return 0; /* dont pass it on */
+// printf("SHOW EVENT %p\n", ee);
+ ee->visible = 1;
+ if (ee->func.fn_show) ee->func.fn_show(ee);
+ return 1;
+}
+
+static int
+_ecore_evas_x_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Evas *ee;
+ Ecore_X_Event_Window_Hide *e;
+
+ e = event;
+ ee = ecore_event_window_match(e->win);
+ if (!ee) return 1; /* pass on event */
+ if (e->win != ee->prop.window) return 1;
+ if (!ee->visible) return 0; /* dont pass it on */
+// printf("HIDE EVENT %p\n", ee);
+ ee->visible = 0;
+ if (ee->func.fn_hide) ee->func.fn_hide(ee);
+ return 1;
+}
+
+/* FIXME, should be in idler */
+/* FIXME, round trip */
+static void
+_ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee)
+{
+# ifdef HAVE_ECORE_X_XCB
+ ecore_x_icccm_size_pos_hints_get_prefetch(ee->prop.window);
+ ecore_x_icccm_size_pos_hints_get_fetch();
+# endif /* HAVE_ECORE_X_XCB */
+ ecore_x_icccm_size_pos_hints_set(ee->prop.window,
+ ee->prop.request_pos /*request_pos */,
+ ECORE_X_GRAVITY_NW /* gravity */,
+ ee->prop.min.w /* min_w */,
+ ee->prop.min.h /* min_h */,
+ ee->prop.max.w /* max_w */,
+ ee->prop.max.h /* max_h */,
+ ee->prop.base.w /* base_w */,
+ ee->prop.base.h /* base_h */,
+ ee->prop.step.w /* step_x */,
+ ee->prop.step.h /* step_y */,
+ 0 /* min_aspect */,
+ 0 /* max_aspect */);
+# ifdef HAVE_ECORE_X_XCB
+ ecore_xcb_reply_free();
+# endif /* HAVE_ECORE_X_XCB */
+}
+
+/* FIXME, should be in idler */
+static void
+_ecore_evas_x_state_update(Ecore_Evas *ee)
+{
+ Ecore_X_Window_State state[10];
+ int num;
+
+ num = 0;
+
+ /*
+ if (bd->client.netwm.state.modal)
+ state[num++] = ECORE_X_WINDOW_STATE_MODAL;
+ */
+ if (ee->engine.x.state.sticky)
+ state[num++] = ECORE_X_WINDOW_STATE_STICKY;
+ /*
+ if (bd->client.netwm.state.maximized_v)
+ state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
+ if (bd->client.netwm.state.maximized_h)
+ state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
+ if (bd->client.netwm.state.shaded)
+ state[num++] = ECORE_X_WINDOW_STATE_SHADED;
+ if (bd->client.netwm.state.skip_taskbar)
+ state[num++] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
+ if (bd->client.netwm.state.skip_pager)
+ state[num++] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
+ if (bd->client.netwm.state.hidden)
+ state[num++] = ECORE_X_WINDOW_STATE_HIDDEN;
+ */
+ if (ee->engine.x.state.fullscreen)
+ state[num++] = ECORE_X_WINDOW_STATE_FULLSCREEN;
+ if (ee->engine.x.state.above)
+ state[num++] = ECORE_X_WINDOW_STATE_ABOVE;
+ if (ee->engine.x.state.below)
+ state[num++] = ECORE_X_WINDOW_STATE_BELOW;
+
+ ecore_x_netwm_window_state_set(ee->prop.window, state, num);
+}
+
+static void
+_ecore_evas_x_layer_update(Ecore_Evas *ee)
+{
+ if (ee->should_be_visible)
+ {
+ /* We need to send a netwm request to the wm */
+ /* FIXME: Do we have to remove old state before adding new? */
+ if (ee->prop.layer < 3)
+ {
+ if (ee->engine.x.state.above)
+ {
+ ee->engine.x.state.above = 0;
+ ecore_x_netwm_state_request_send(ee->prop.window,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
+ }
+ if (!ee->engine.x.state.below)
+ {
+ ee->engine.x.state.below = 1;
+ ecore_x_netwm_state_request_send(ee->prop.window,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_BELOW, -1, 1);
+ }
+ }
+ else if (ee->prop.layer > 5)
+ {
+ if (ee->engine.x.state.below)
+ {
+ ee->engine.x.state.below = 0;
+ ecore_x_netwm_state_request_send(ee->prop.window,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_BELOW, -1, 0);
+ }
+ if (!ee->engine.x.state.above)
+ {
+ ee->engine.x.state.above = 1;
+ ecore_x_netwm_state_request_send(ee->prop.window,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_ABOVE, -1, 1);
+ }
+ }
+ else
+ {
+ if (ee->engine.x.state.below)
+ {
+ ee->engine.x.state.below = 0;
+ ecore_x_netwm_state_request_send(ee->prop.window,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_BELOW, -1, 0);
+ }
+ if (ee->engine.x.state.above)
+ {
+ ee->engine.x.state.above = 0;
+ ecore_x_netwm_state_request_send(ee->prop.window,
+ ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
+ }
+ }
+ }
+ else
+ {
+ /* Just set the state */
+ if (ee->prop.layer < 3)
+ {
+ if ((ee->engine.x.state.above) || (!ee->engine.x.state.below))
+ {
+ ee->engine.x.state.above = 0;
+ ee->engine.x.state.below = 1;
+ _ecore_evas_x_state_update(ee);
+ }
+ }
+ else if (ee->prop.layer > 5)
+ {
+ if ((!ee->engine.x.state.above) || (ee->engine.x.state.below))
+ {
+ ee->engine.x.state.above = 1;
+ ee->engine.x.state.below = 0;
+ _ecore_evas_x_state_update(ee);
+ }
+ }
+ else
+ {
+ if ((ee->engine.x.state.above) || (ee->engine.x.state.below))
+ {
+ ee->engine.x.state.above = 0;
+ ee->engine.x.state.below = 0;
+ _ecore_evas_x_state_update(ee);
+ }
+ }
+ }
+ /* FIXME: Set gnome layer */
+}
+
+static int
+_ecore_evas_x_init(void)
+{
+ _ecore_evas_init_count++;
+ if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+ ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _ecore_evas_x_event_mouse_in, NULL);
+ ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _ecore_evas_x_event_mouse_out, NULL);
+ ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _ecore_evas_x_event_window_focus_in, NULL);
+ ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _ecore_evas_x_event_window_focus_out, NULL);
+ ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, _ecore_evas_x_event_window_damage, NULL);
+ ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _ecore_evas_x_event_window_destroy, NULL);
+ ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _ecore_evas_x_event_window_configure, NULL);
+ ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, _ecore_evas_x_event_window_delete_request, NULL);
+ ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, _ecore_evas_x_event_window_show, NULL);
+ ecore_evas_event_handlers[9] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _ecore_evas_x_event_window_hide, NULL);
+ ecore_evas_event_handlers[10] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _ecore_evas_x_event_property_change, NULL);
+ ecore_evas_event_handlers[11] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, _ecore_evas_x_event_visibility_change, NULL);
+ ecore_evas_event_handlers[12] = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _ecore_evas_x_event_client_message, NULL);
+ ecore_event_evas_init();
+ return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_x_free(Ecore_Evas *ee)
+{
+ _ecore_evas_x_sync_set(ee);
+ ecore_x_window_free(ee->prop.window);
+ if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
+ if (ee->engine.x.damages) ecore_x_xregion_free(ee->engine.x.damages);
+ ee->engine.x.pmap = 0;
+ ee->engine.x.mask = 0;
+ ee->engine.x.gc = 0;
+ ee->engine.x.damages = NULL;
+ ecore_event_window_unregister(ee->prop.window);
+ while (ee->engine.x.win_extra)
+ {
+ Ecore_X_Window *winp;
+
+ winp = ee->engine.x.win_extra->data;
+ ee->engine.x.win_extra = eina_list_remove_list(ee->engine.x.win_extra, ee->engine.x.win_extra);
+ ecore_event_window_unregister(*winp);
+ free(winp);
+ }
+ _ecore_evas_x_shutdown();
+ ecore_x_shutdown();
+}
+
+static void
+_ecore_evas_x_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
+{
+ ee->func.fn_delete_request = func;
+ _ecore_evas_x_protocols_set(ee);
+ _ecore_evas_x_sync_set(ee);
+}
+
+static void
+_ecore_evas_x_move(Ecore_Evas *ee, int x, int y)
+{
+ ee->req.x = x;
+ ee->req.y = y;
+ if (ee->engine.x.direct_resize)
+ {
+ if (!ee->engine.x.managed)
+ {
+ if ((x != ee->x) || (y != ee->y))
+ {
+ ee->x = x;
+ ee->y = y;
+ ecore_x_window_move(ee->prop.window, x, y);
+ if (!ee->should_be_visible)
+ {
+ /* We need to request pos */
+ ee->prop.request_pos = 1;
+ _ecore_evas_x_size_pos_hints_update(ee);
+ }
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+ }
+ }
+ else
+ {
+ ecore_x_window_move(ee->prop.window, x, y);
+ if (!ee->should_be_visible)
+ {
+ /* We need to request pos */
+ ee->prop.request_pos = 1;
+ _ecore_evas_x_size_pos_hints_update(ee);
+ }
+ if (!ee->engine.x.managed)
+ {
+ ee->x = x;
+ ee->y = y;
+ }
+ }
+}
+
+static void
+_ecore_evas_x_managed_move(Ecore_Evas *ee, int x, int y)
+{
+ ee->req.x = x;
+ ee->req.y = y;
+ if (ee->engine.x.direct_resize)
+ {
+ ee->engine.x.managed = 1;
+ if ((x != ee->x) || (y != ee->y))
+ {
+ ee->x = x;
+ ee->y = y;
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+ }
+}
+
+static void
+_ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
+{
+ ee->req.w = w;
+ ee->req.h = h;
+ if (ee->engine.x.direct_resize)
+ {
+ if ((ee->w != w) || (ee->h != h))
+ {
+ ecore_x_window_resize(ee->prop.window, w, h);
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ int pdam;
+
+ pdam = ecore_evas_avoid_damage_get(ee);
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, pdam);
+ }
+ if ((ee->shaped) || (ee->alpha))
+ _ecore_evas_x_resize_shape(ee);
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ }
+ else
+ ecore_x_window_resize(ee->prop.window, w, h);
+}
+
+static void
+_ecore_evas_x_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
+{
+ ee->req.x = x;
+ ee->req.y = y;
+ ee->req.w = w;
+ ee->req.h = h;
+ if (ee->engine.x.direct_resize)
+ {
+ if ((ee->w != w) || (ee->h != h) || (x != ee->x) || (y != ee->y))
+ {
+ int change_size = 0, change_pos = 0;
+
+ if ((ee->w != w) || (ee->h != h)) change_size = 1;
+ if (!ee->engine.x.managed)
+ {
+ if ((x != ee->x) || (y != ee->y)) change_pos = 1;
+ }
+ ecore_x_window_move_resize(ee->prop.window, x, y, w, h);
+ if (!ee->engine.x.managed)
+ {
+ ee->x = x;
+ ee->y = y;
+ }
+ ee->w = w;
+ ee->h = h;
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ if (ee->prop.avoid_damage)
+ {
+ int pdam;
+
+ pdam = ecore_evas_avoid_damage_get(ee);
+ ecore_evas_avoid_damage_set(ee, 0);
+ ecore_evas_avoid_damage_set(ee, pdam);
+ }
+ if ((ee->shaped) || (ee->alpha))
+ _ecore_evas_x_resize_shape(ee);
+ if (change_pos)
+ {
+ if (ee->func.fn_move) ee->func.fn_move(ee);
+ }
+ if (change_size)
+ {
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ }
+ }
+ else
+ {
+ ecore_x_window_move_resize(ee->prop.window, x, y, w, h);
+ if (!ee->engine.x.managed)
+ {
+ ee->x = x;
+ ee->y = y;
+ }
+ }
+}
+
+static void
+_ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
+ Evas_Engine_Info *einfo)
+{
+ int rot_dif;
+
+ rot_dif = ee->rotation - rotation;
+ if (rot_dif < 0) rot_dif = -rot_dif;
+
+ if (rot_dif != 180)
+ {
+ int minw, minh, maxw, maxh, basew, baseh, stepw, steph;
+
+ if (!evas_engine_info_set(ee->evas, einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+
+ if (!resize)
+ {
+ if (!ee->prop.fullscreen)
+ {
+ ecore_x_window_resize(ee->prop.window, ee->req.h, ee->req.w);
+ ee->expecting_resize.w = ee->h;
+ ee->expecting_resize.h = ee->w;
+ }
+ else
+ {
+ int w, h;
+
+ ecore_x_window_size_get(ee->prop.window, &w, &h);
+ ecore_x_window_resize(ee->prop.window, h, w);
+ if ((rotation == 0) || (rotation == 180))
+ {
+ evas_output_size_set(ee->evas, ee->req.w, ee->req.h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->req.w, ee->req.h);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->req.h, ee->req.w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->req.h, ee->req.w);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
+ }
+ else
+ {
+ int w, h;
+
+ ecore_x_window_size_get(ee->prop.window, &w, &h);
+ if ((rotation == 0) || (rotation == 180))
+ {
+ evas_output_size_set(ee->evas, ee->w, ee->h);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ evas_output_size_set(ee->evas, ee->h, ee->w);
+ evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ }
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ ecore_evas_size_min_get(ee, &minw, &minh);
+ ecore_evas_size_max_get(ee, &maxw, &maxh);
+ ecore_evas_size_base_get(ee, &basew, &baseh);
+ ecore_evas_size_step_get(ee, &stepw, &steph);
+ ee->rotation = rotation;
+ ecore_evas_size_min_set(ee, minh, minw);
+ ecore_evas_size_max_set(ee, maxh, maxw);
+ ecore_evas_size_base_set(ee, baseh, basew);
+ ecore_evas_size_step_set(ee, steph, stepw);
+ _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_x_current_time_get());
+ }
+ else
+ {
+ if (!evas_engine_info_set(ee->evas, einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ ee->rotation = rotation;
+ _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
+ ecore_x_current_time_get());
+ if (ee->func.fn_resize) ee->func.fn_resize(ee);
+
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+}
+
+static void
+_ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
+{
+ if (ee->rotation == rotation) return;
+ if (!strcmp(ee->driver, "xrender_x11")) return;
+ if (!strcmp(ee->driver, "opengl_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+ Evas_Engine_Info_GL_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ einfo->info.rotation = rotation;
+ _ecore_evas_x_rotation_set_internal
+ (ee, rotation, resize, (Evas_Engine_Info *)einfo);
+#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
+ }
+ else if (!strcmp(ee->driver, "software_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ einfo->info.rotation = rotation;
+ _ecore_evas_x_rotation_set_internal
+ (ee, rotation, resize, (Evas_Engine_Info *)einfo);
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
+ }
+ else if (!strcmp(ee->driver, "software_16_x11"))
+ {
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+ Evas_Engine_Info_Software_16_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ einfo->info.rotation = rotation;
+ _ecore_evas_x_rotation_set_internal
+ (ee, rotation, resize, (Evas_Engine_Info *)einfo);
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+ }
+}
+
+static void
+_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
+{
+ if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped)))
+ return;
+ if (!strcmp(ee->driver, "opengl_x11")) return;
+ if (!strcmp(ee->driver, "software_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ ee->shaped = shaped;
+ if (einfo)
+ {
+ if (ee->shaped)
+ {
+ unsigned int foreground;
+ Ecore_X_GC gc;
+
+ if (!ee->engine.x.mask)
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
+ foreground = 0;
+ gc = ecore_x_gc_new(ee->engine.x.mask,
+ ECORE_X_GC_VALUE_MASK_FOREGROUND,
+ &foreground);
+ ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
+ 0, 0, ee->w, ee->h);
+ ecore_x_gc_free(gc);
+ einfo->info.mask = ee->engine.x.mask;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+ else
+ {
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ einfo->info.mask = 0;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ ecore_x_window_shape_mask_set(ee->prop.window, 0);
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+ }
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
+ }
+ else if (!strcmp(ee->driver, "xrender_x11"))
+ {
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+ Evas_Engine_Info_XRender_X11 *einfo;
+
+ ee->shaped = shaped;
+ einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ if (ee->shaped)
+ {
+ unsigned int foreground;
+ Ecore_X_GC gc;
+
+ if (!ee->engine.x.mask)
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
+ foreground = 0;
+ gc = ecore_x_gc_new(ee->engine.x.mask,
+ ECORE_X_GC_VALUE_MASK_FOREGROUND,
+ &foreground);
+ ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
+ 0, 0, ee->w, ee->h);
+ ecore_x_gc_free(gc);
+ einfo->info.mask = ee->engine.x.mask;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+ else
+ {
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ einfo->info.mask = 0;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ ecore_x_window_shape_mask_set(ee->prop.window, 0);
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+ }
+#endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
+ }
+ else if (!strcmp(ee->driver, "software_16_x11"))
+ {
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+# if 0 /* XXX no shaped window support for software_16_x11 */
+ Evas_Engine_Info_Software_16_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
+ ee->shaped = shaped;
+ if (einfo)
+ {
+ if (ee->shaped)
+ {
+ GC gc;
+ XGCValues gcv;
+
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
+ einfo->info.mask = ee->engine.x.mask;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ }
+ else
+ {
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ einfo->info.mask = 0;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ ecore_x_window_shape_mask_set(ee->prop.window, 0);
+ }
+ }
+# endif /* XXX no shaped window support for software_16_x11 */
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+ }
+
+}
+
+/* FIXME, round trip */
+static void
+_ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
+{
+# ifdef HAVE_ECORE_X_XCB
+ xcb_get_geometry_cookie_t cookie_geom;
+ xcb_get_window_attributes_cookie_t cookie_attr;
+ xcb_get_geometry_reply_t *reply_geom;
+ xcb_get_window_attributes_reply_t *reply_attr;
+#else
+ XWindowAttributes att;
+#endif /* ! HAVE_ECORE_X_XCB */
+
+ if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha)))
+ return;
+
+ if (!strcmp(ee->driver, "software_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+
+ if (!ecore_x_composite_query()) return;
+
+ ee->shaped = 0;
+ ee->alpha = alpha;
+ ecore_x_window_free(ee->prop.window);
+ ecore_event_window_unregister(ee->prop.window);
+ if (ee->alpha)
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (!ee->engine.x.mask)
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
+ }
+ else
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+
+ einfo->info.destination_alpha = alpha;
+
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+ cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
+ cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
+
+ reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
+ reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
+ einfo->info.visual = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
+ einfo->info.colormap = reply_attr->colormap;
+ einfo->info.depth = reply_geom->depth;
+ free(reply_geom);
+ free(reply_attr);
+# else
+ XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
+ einfo->info.visual = att.visual;
+ einfo->info.colormap = att.colormap;
+ einfo->info.depth = att.depth;
+# endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
+
+// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+// ee->engine.x.mask = 0;
+ einfo->info.mask = ee->engine.x.mask;
+ einfo->info.drawable = ee->prop.window;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
+ ecore_x_window_shape_mask_set(ee->prop.window, 0);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ if (ee->prop.borderless)
+ ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
+ if (ee->visible) ecore_x_window_show(ee->prop.window);
+ if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
+ if (ee->prop.title)
+ {
+ ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
+ ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
+ }
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ _ecore_evas_x_protocols_set(ee);
+ _ecore_evas_x_sync_set(ee);
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+ // putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+ }
+ else if (!strcmp(ee->driver, "opengl_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+ Evas_Engine_Info_GL_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+
+ if (!ecore_x_composite_query()) return;
+
+ ee->shaped = 0;
+ ee->alpha = alpha;
+ ecore_x_window_free(ee->prop.window);
+ ecore_event_window_unregister(ee->prop.window);
+ ee->prop.window = 0;
+
+ einfo->info.destination_alpha = alpha;
+
+ if (ee->engine.x.win_root != 0)
+ {
+ /* FIXME: round trip in ecore_x_window_argb_get */
+ if (ecore_x_window_argb_get(ee->engine.x.win_root))
+ {
+ ee->prop.window = _ecore_evas_x_gl_window_new
+ (ee, ee->engine.x.win_root,
+ ee->req.x, ee->req.y, ee->req.w, ee->req.h,
+ ee->prop.override, 1, NULL);
+ }
+ else
+ ee->prop.window = _ecore_evas_x_gl_window_new
+ (ee, ee->engine.x.win_root,
+ ee->req.x, ee->req.y, ee->req.w, ee->req.h,
+ ee->prop.override, ee->alpha, NULL);
+ }
+ else
+ ee->prop.window = _ecore_evas_x_gl_window_new
+ (ee, ee->engine.x.win_root,
+ ee->req.x, ee->req.y, ee->req.w, ee->req.h,
+ ee->prop.override, ee->alpha, NULL);
+ if (!ee->prop.window)
+ {
+ return;
+ }
+/*
+ if (ee->alpha)
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (!ee->engine.x.mask)
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
+ }
+ else
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+ */
+
+ XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
+ einfo->info.visual = att.visual;
+ einfo->info.colormap = att.colormap;
+ einfo->info.depth = att.depth;
+
+// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+// ee->engine.x.mask = 0;
+// einfo->info.mask = ee->engine.x.mask;
+ einfo->info.drawable = ee->prop.window;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
+// ecore_x_window_shape_mask_set(ee->prop.window, 0);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ if (ee->prop.borderless)
+ ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
+ if (ee->visible) ecore_x_window_show(ee->prop.window);
+ if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
+ if (ee->prop.title)
+ {
+ ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
+ ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
+ }
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ _ecore_evas_x_protocols_set(ee);
+ _ecore_evas_x_sync_set(ee);
+#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+ // putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+ }
+ else if (!strcmp(ee->driver, "xrender_x11"))
+ {
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+ Evas_Engine_Info_XRender_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+ if (!ecore_x_composite_query()) return;
+
+ ee->shaped = 0;
+ ee->alpha = alpha;
+ ecore_x_window_free(ee->prop.window);
+ ecore_event_window_unregister(ee->prop.window);
+ if (ee->alpha)
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (!ee->engine.x.mask)
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
+ }
+ else
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+
+ einfo->info.destination_alpha = alpha;
+
+# ifdef BUILD_ECORE_EVAS_XRENDER_XCB
+ cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
+ reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
+
+ einfo->info.visual = reply_attr->visual;
+ free(reply_attr);
+# else
+ XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
+ einfo->info.visual = att.visual;
+# endif /* ! BUILD_ECORE_EVAS_XRENDER_XCB */
+
+// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+// ee->engine.x.mask = 0;
+ einfo->info.mask = ee->engine.x.mask;
+ einfo->info.drawable = ee->prop.window;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
+ ecore_x_window_shape_mask_set(ee->prop.window, 0);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ if (ee->prop.borderless)
+ ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
+ if (ee->visible) ecore_x_window_show(ee->prop.window);
+ if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
+ if (ee->prop.title)
+ {
+ ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
+ ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
+ }
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ _ecore_evas_x_protocols_set(ee);
+ _ecore_evas_x_sync_set(ee);
+#endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+ // putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+ }
+ else if (!strcmp(ee->driver, "software_16_x11"))
+ {
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+ Evas_Engine_Info_Software_16_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+
+ ee->shaped = 0;
+ ee->alpha = alpha;
+ ecore_x_window_free(ee->prop.window);
+ ecore_event_window_unregister(ee->prop.window);
+ if (ee->alpha)
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (!ee->engine.x.mask)
+ ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
+ }
+ else
+ {
+ if (ee->prop.override)
+ ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ else
+ ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
+ if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+ ee->engine.x.mask = 0;
+ ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
+ }
+
+# if 0 /* XXX no alpha window support for software_16_x11 */
+ einfo->info.destination_alpha = alpha;
+# endif /* XXX no alpha window support for software_16_x11 */
+
+# if 0 /* XXX no shaped window support for software_16_x11 */
+// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
+// ee->engine.x.mask = 0;
+ einfo->info.mask = ee->engine.x.mask;
+# endif /* XXX no shaped window support for software_16_x11 */
+
+ einfo->info.drawable = ee->prop.window;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
+ ecore_x_window_shape_mask_set(ee->prop.window, 0);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ if (ee->prop.borderless)
+ ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
+ if (ee->visible) ecore_x_window_show(ee->prop.window);
+ if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
+ if (ee->prop.title)
+ {
+ ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
+ ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
+ }
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ _ecore_evas_x_protocols_set(ee);
+ _ecore_evas_x_sync_set(ee);
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+ // putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+ }
+}
+
+static void
+_ecore_evas_x_transparent_set(Ecore_Evas *ee, int transparent)
+{
+ if (((ee->transparent) && (transparent)) ||
+ ((!ee->transparent) && (!transparent)))
+ return;
+
+ if (!strcmp(ee->driver, "software_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (!einfo) return;
+
+ ee->transparent = transparent;
+ einfo->info.destination_alpha = transparent;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+#endif
+ }
+}
+#endif /* BUILD_ECORE_EVAS_X11 */
+
+#ifdef BUILD_ECORE_EVAS_X11
+static void
+_ecore_evas_x_show(Ecore_Evas *ee)
+{
+ ee->should_be_visible = 1;
+ if (ee->prop.avoid_damage)
+ _ecore_evas_x_render(ee);
+ ecore_x_window_show(ee->prop.window);
+ if (ee->prop.fullscreen)
+ ecore_x_window_focus(ee->prop.window);
+}
+
+static void
+_ecore_evas_x_hide(Ecore_Evas *ee)
+{
+ ecore_x_window_hide(ee->prop.window);
+ ee->should_be_visible = 0;
+}
+
+static void
+_ecore_evas_x_raise(Ecore_Evas *ee)
+{
+ if (!ee->prop.fullscreen)
+ ecore_x_window_raise(ee->prop.window);
+ else
+ ecore_x_window_raise(ee->prop.window);
+}
+
+static void
+_ecore_evas_x_lower(Ecore_Evas *ee)
+{
+ if (!ee->prop.fullscreen)
+ ecore_x_window_lower(ee->prop.window);
+ else
+ ecore_x_window_lower(ee->prop.window);
+}
+
+static void
+_ecore_evas_x_activate(Ecore_Evas *ee)
+{
+ ecore_x_netwm_client_active_request(ee->engine.x.win_root,
+ ee->prop.window, 2, 0);
+}
+
+static void
+_ecore_evas_x_title_set(Ecore_Evas *ee, const char *t)
+{
+ if (ee->prop.title) free(ee->prop.title);
+ ee->prop.title = NULL;
+ if (t) ee->prop.title = strdup(t);
+ ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
+ ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
+}
+
+static void
+_ecore_evas_x_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
+{
+ if (ee->prop.name) free(ee->prop.name);
+ if (ee->prop.clas) free(ee->prop.clas);
+ ee->prop.name = NULL;
+ ee->prop.clas = NULL;
+ if (n) ee->prop.name = strdup(n);
+ if (c) ee->prop.clas = strdup(c);
+ ecore_x_icccm_name_class_set(ee->prop.window, ee->prop.name, ee->prop.clas);
+}
+
+static void
+_ecore_evas_x_size_min_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
+ ee->prop.min.w = w;
+ ee->prop.min.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_x_size_max_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
+ ee->prop.max.w = w;
+ ee->prop.max.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_x_size_base_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+ if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
+ ee->prop.base.w = w;
+ ee->prop.base.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_x_size_step_set(Ecore_Evas *ee, int w, int h)
+{
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
+ ee->prop.step.w = w;
+ ee->prop.step.h = h;
+ _ecore_evas_x_size_pos_hints_update(ee);
+}
+
+static void
+_ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee;
+
+ ee = data;
+ if (ee)
+ ee->prop.cursor.object = NULL;
+}
+
+static void
+_ecore_evas_x_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+ int x, y;
+
+ if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+ if (obj == NULL)
+ {
+ ee->prop.cursor.object = NULL;
+ ee->prop.cursor.layer = 0;
+ ee->prop.cursor.hot.x = 0;
+ ee->prop.cursor.hot.y = 0;
+ ecore_x_window_cursor_show(ee->prop.window, 1);
+ return;
+ }
+
+ ee->prop.cursor.object = obj;
+ ee->prop.cursor.layer = layer;
+ ee->prop.cursor.hot.x = hot_x;
+ ee->prop.cursor.hot.y = hot_y;
+
+ ecore_x_window_cursor_show(ee->prop.window, 0);
+
+ evas_pointer_output_xy_get(ee->evas, &x, &y);
+ evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+ evas_object_move(ee->prop.cursor.object,
+ x - ee->prop.cursor.hot.x,
+ y - ee->prop.cursor.hot.y);
+ evas_object_pass_events_set(ee->prop.cursor.object, 1);
+ if (evas_pointer_inside_get(ee->evas))
+ evas_object_show(ee->prop.cursor.object);
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
+}
+
+/*
+ * @param ee
+ * @param layer If < 3, @a ee will be put below all other windows.
+ * If > 5, @a ee will be "always-on-top"
+ * If = 4, @a ee will be put in the default layer.
+ * Acceptable values range from 1 to 255 (0 reserved for
+ * desktop windows)
+ */
+static void
+_ecore_evas_x_layer_set(Ecore_Evas *ee, int layer)
+{
+ if (ee->prop.layer == layer) return;
+
+ /* FIXME: Should this logic be here? */
+ if (layer < 1)
+ layer = 1;
+ else if (layer > 255)
+ layer = 255;
+
+ ee->prop.layer = layer;
+ _ecore_evas_x_layer_update(ee);
+}
+
+static void
+_ecore_evas_x_focus_set(Ecore_Evas *ee, int on __UNUSED__)
+{
+ ecore_x_window_focus(ee->prop.window);
+}
+
+static void
+_ecore_evas_x_iconified_set(Ecore_Evas *ee, int on)
+{
+// if (((ee->prop.iconified) && (on)) ||
+// ((!ee->prop.iconified) && (!on))) return;
+ ee->prop.iconified = on;
+ if (on)
+ {
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_ICONIC /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root);
+ }
+ else
+ {
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+ ecore_evas_show(ee);
+ }
+}
+
+static void
+_ecore_evas_x_borderless_set(Ecore_Evas *ee, int on)
+{
+ if (((ee->prop.borderless) && (on)) ||
+ ((!ee->prop.borderless) && (!on))) return;
+ ee->prop.borderless = on;
+ ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
+}
+
+/* FIXME: This function changes the initial state of the ee
+ * whilest the iconic function changes the current state! */
+static void
+_ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn)
+{
+ Ecore_X_Window_State_Hint hint;
+
+ if ((ee->prop.withdrawn && withdrawn) ||
+ (!ee->prop.withdrawn && !withdrawn)) return;
+
+ ee->prop.withdrawn = withdrawn;
+ if (withdrawn)
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ hint /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+}
+
+static void
+_ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky)
+{
+ if ((ee->prop.sticky && sticky) ||
+ (!ee->prop.sticky && !sticky)) return;
+
+ /* We dont want to set prop.sticky here as it will cause
+ * the sticky callback not to get called. Its set on the
+ * property change event.
+ * ee->prop.sticky = sticky;
+ */
+ ee->engine.x.state.sticky = sticky;
+ if (ee->should_be_visible)
+ ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_STICKY, -1, sticky);
+ else
+ _ecore_evas_x_state_update(ee);
+}
+
+static void
+_ecore_evas_x_ignore_events_set(Ecore_Evas *ee, int ignore)
+{
+ if ((ee->ignore_events && ignore) ||
+ (!ee->ignore_events && !ignore)) return;
+
+ if (ignore)
+ {
+ ee->ignore_events = 1;
+ if (ee->prop.window)
+ ecore_x_window_ignore_set(ee->prop.window, 1);
+ }
+ else
+ {
+ ee->ignore_events = 0;
+ if (ee->prop.window)
+ ecore_x_window_ignore_set(ee->prop.window, 0);
+ }
+}
+
+/*
+static void
+_ecore_evas_x_reinit_win(Ecore_Evas *ee)
+{
+ if (!strcmp(ee->driver, "software_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_X11
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.drawable = ee->prop.window;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+#endif
+ }
+ else if (!strcmp(ee->driver, "xrender_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_XRENDER_X11
+ Evas_Engine_Info_XRender_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.drawable = ee->prop.window;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+#endif
+ }
+ else if (!strcmp(ee->driver, "opengl_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+ Evas_Engine_Info_GL_X11 *einfo;
+
+ einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->info.drawable = ee->prop.window;
+ evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+ }
+#endif
+ }
+}
+*/
+
+static void
+_ecore_evas_x_override_set(Ecore_Evas *ee, int on)
+{
+ if (((ee->prop.override) && (on)) ||
+ ((!ee->prop.override) && (!on))) return;
+ ecore_x_window_hide(ee->prop.window);
+ ecore_x_window_override_set(ee->prop.window, on);
+ if (ee->visible) ecore_x_window_show(ee->prop.window);
+ if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
+ ee->prop.override = on;
+}
+
+static void
+_ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on)
+{
+ if ((ee->prop.fullscreen && on) ||
+ (!ee->prop.fullscreen && !on)) return;
+
+ /* FIXME: Detect if WM is EWMH compliant and handle properly if not,
+ * i.e. reposition, resize, and change borderless hint */
+ ee->engine.x.state.fullscreen = on;
+ if (ee->should_be_visible)
+ ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
+ ECORE_X_WINDOW_STATE_FULLSCREEN, -1, on);
+ else
+ _ecore_evas_x_state_update(ee);
+}
+
+static void
+_ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
+{
+ if (ee->prop.avoid_damage == on) return;
+ if (!strcmp(ee->driver, "opengl_x11")) return;
+ if (!strcmp(ee->driver, "xrender_x11")) return;
+
+ if (!strcmp(ee->driver, "software_x11"))
+ {
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+ Evas_Engine_Info_Software_X11 *einfo;
+
+ ee->prop.avoid_damage = on;
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ if (ee->prop.avoid_damage)
+ {
+ ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
+ ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
+ einfo->info.drawable = ee->engine.x.pmap;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
+ {
+ ee->engine.x.using_bg_pixmap = 1;
+ ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
+ ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
+ }
+ if (ee->engine.x.direct_resize)
+ {
+ /* Turn this off for now
+ ee->engine.x.using_bg_pixmap = 1;
+ ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
+ */
+ }
+ }
+ else
+ {
+ if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
+ if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
+ if (ee->engine.x.using_bg_pixmap)
+ {
+ ecore_x_window_pixmap_set(ee->prop.window, 0);
+ ee->engine.x.using_bg_pixmap = 0;
+ ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
+ }
+ ee->engine.x.pmap = 0;
+ ee->engine.x.gc = 0;
+ einfo->info.drawable = ee->prop.window;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ }
+ }
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
+ }
+ else if (!strcmp(ee->driver, "software_16_x11"))
+ {
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+ Evas_Engine_Info_Software_16_X11 *einfo;
+ ee->prop.avoid_damage = on;
+
+ einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ if (ee->prop.avoid_damage)
+ {
+ ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 16);
+ ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
+ einfo->info.drawable = ee->engine.x.pmap;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ if ((ee->rotation == 90) || (ee->rotation == 270))
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+ else
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+ if (ee->engine.x.direct_resize)
+ {
+ /* Turn this off for now
+ ee->engine.x.using_bg_pixmap = 1;
+ ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
+ */
+ }
+ }
+ else
+ {
+ if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
+ if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
+ if (ee->engine.x.using_bg_pixmap)
+ {
+ ecore_x_window_pixmap_set(ee->prop.window, 0);
+ ee->engine.x.using_bg_pixmap = 0;
+ }
+ ee->engine.x.pmap = 0;
+ ee->engine.x.gc = 0;
+ einfo->info.drawable = ee->prop.window;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ }
+ }
+#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+ }
+}
+
+int
+_ecore_evas_x_shutdown(void)
+{
+ _ecore_evas_init_count--;
+ if (_ecore_evas_init_count == 0)
+ {
+ unsigned int i;
+
+ for (i = 0; i < sizeof(ecore_evas_event_handlers) / sizeof(Ecore_Event_Handler*); i++)
+ {
+ if (ecore_evas_event_handlers[i])
+ ecore_event_handler_del(ecore_evas_event_handlers[i]);
+ }
+ ecore_event_evas_shutdown();
+ }
+ if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+ return _ecore_evas_init_count;
+}
+
+static Ecore_Evas_Engine_Func _ecore_x_engine_func =
+{
+ _ecore_evas_x_free,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_x_callback_delete_request_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_x_move,
+ _ecore_evas_x_managed_move,
+ _ecore_evas_x_resize,
+ _ecore_evas_x_move_resize,
+ _ecore_evas_x_rotation_set,
+ _ecore_evas_x_shaped_set,
+ _ecore_evas_x_show,
+ _ecore_evas_x_hide,
+ _ecore_evas_x_raise,
+ _ecore_evas_x_lower,
+ _ecore_evas_x_activate,
+ _ecore_evas_x_title_set,
+ _ecore_evas_x_name_class_set,
+ _ecore_evas_x_size_min_set,
+ _ecore_evas_x_size_max_set,
+ _ecore_evas_x_size_base_set,
+ _ecore_evas_x_size_step_set,
+ _ecore_evas_x_object_cursor_set,
+ _ecore_evas_x_layer_set,
+ _ecore_evas_x_focus_set,
+ _ecore_evas_x_iconified_set,
+ _ecore_evas_x_borderless_set,
+ _ecore_evas_x_override_set,
+ NULL,
+ _ecore_evas_x_fullscreen_set,
+ _ecore_evas_x_avoid_damage_set,
+ _ecore_evas_x_withdrawn_set,
+ _ecore_evas_x_sticky_set,
+ _ecore_evas_x_ignore_events_set,
+ _ecore_evas_x_alpha_set,
+ _ecore_evas_x_transparent_set,
+
+ NULL // render
+};
+#endif /* BUILD_ECORE_EVAS_X11 */
+
+/*
+ * FIXME: there are some round trips. Especially, we can split
+ * ecore_x_init in 2 functions and supress some round trips.
+ */
+
+#if defined (BUILD_ECORE_EVAS_SOFTWARE_X11) || defined (BUILD_ECORE_EVAS_OPENGL_X11) || defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB) || defined (BUILD_ECORE_EVAS_SOFTWARE_16_X11)
+static void
+_ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+
+ if (ee->no_comp_sync) return;
+ if (!_ecore_evas_app_comp_sync) return;
+ if (ee->engine.x.sync_counter)
+ {
+ if (ee->engine.x.sync_began)
+ {
+ ee->engine.x.sync_val++;
+ if (!ee->engine.x.sync_cancel)
+ {
+ ecore_x_sync_counter_val_wait(ee->engine.x.sync_counter,
+ ee->engine.x.sync_val);
+ }
+ }
+ }
+}
+
+static void
+_ecore_evas_x_flush_post(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
+{
+ Ecore_Evas *ee = data;
+
+ if (ee->no_comp_sync) return;
+ if (!_ecore_evas_app_comp_sync) return;
+ if (ee->engine.x.sync_counter)
+ {
+ if (ee->engine.x.sync_began)
+ {
+ if (!ee->engine.x.sync_cancel)
+ {
+ ecore_x_e_comp_sync_draw_done_send(ee->engine.x.win_root,
+ ee->prop.window);
+ }
+ }
+ }
+}
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+EAPI Ecore_Evas *
+ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h)
+{
+ Evas_Engine_Info_Software_X11 *einfo;
+ Ecore_Evas *ee;
+ int argb = 0;
+ int rmethod;
+ static int redraw_debug = -1;
+
+ rmethod = evas_render_method_lookup("software_x11");
+ if (!rmethod) return NULL;
+ if (!ecore_x_init(disp_name)) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_x_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
+
+ ee->driver = "software_x11";
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = w;
+ ee->h = h;
+ ee->req.x = ee->x;
+ ee->req.y = ee->y;
+ ee->req.w = ee->w;
+ ee->req.h = ee->h;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+ ee->prop.request_pos = 0;
+ ee->prop.sticky = 0;
+ ee->engine.x.state.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.x.win_root = parent;
+ ee->engine.x.screen_num = 0;
+
+ if (parent != 0)
+ {
+ ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
+ /* FIXME: round trip in ecore_x_window_argb_get */
+ if (ecore_x_window_argb_get(parent))
+ {
+ ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
+ argb = 1;
+ }
+ else
+ ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
+ }
+ else
+ ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+// putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+ einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+ xcb_screen_iterator_t iter;
+ xcb_screen_t *screen;
+# else
+ int screen;
+# endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
+
+ /* FIXME: this is inefficient as its a round trip */
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+ screen = ecore_x_default_screen_get();
+ iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
+ if (iter.rem > 1)
+ {
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+ Ecore_X_Window *roots;
+ int num;
+ uint8_t i;
+
+ num = 0;
+ cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
+
+ if (reply)
+ {
+ for (i = 0; i < num; xcb_screen_next (&iter), i++)
+ {
+ if (reply->root == roots[i])
+ {
+ screen = iter.data;
+ break;
+ }
+ }
+ free(reply);
+ }
+ free(roots);
+ }
+ else
+ {
+ reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
+ if (reply) free(reply);
+ }
+ }
+# else
+ screen = DefaultScreen(ecore_x_display_get());
+ if (ScreenCount(ecore_x_display_get()) > 1)
+ {
+ Ecore_X_Window *roots;
+ int num, i;
+
+ num = 0;
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ XWindowAttributes at;
+
+ if (XGetWindowAttributes(ecore_x_display_get(),
+ parent, &at))
+ {
+ for (i = 0; i < num; i++)
+ {
+ if (at.root == roots[i])
+ {
+ screen = i;
+ break;
+ }
+ }
+ }
+ free(roots);
+ }
+ }
+# endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
+
+ if (redraw_debug < 0)
+ {
+ if (getenv("REDRAW_DEBUG"))
+ redraw_debug = atoi(getenv("REDRAW_DEBUG"));
+ else
+ redraw_debug = 0;
+ }
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+ einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB;
+ einfo->info.connection = ecore_x_connection_get();
+ einfo->info.screen = screen;
+# else
+ einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB;
+ einfo->info.connection = ecore_x_display_get();
+ einfo->info.screen = NULL;
+# endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
+ einfo->info.drawable = ee->prop.window;
+ if (argb)
+ {
+ /* FIXME: round trip */
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+ xcb_get_geometry_cookie_t cookie_geom;
+ xcb_get_window_attributes_cookie_t cookie_attr;
+ xcb_get_geometry_reply_t *reply_geom;
+ xcb_get_window_attributes_reply_t *reply_attr;
+
+ cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
+ cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
+
+ reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
+ reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
+ if (reply_attr && reply_geom)
+ {
+ einfo->info.visual = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
+ einfo->info.colormap = reply_attr->colormap;
+ einfo->info.depth = reply_geom->depth;
+ einfo->info.destination_alpha = 1;
+ free(reply_geom);
+ free(reply_attr);
+ }
+# else
+ XWindowAttributes at;
+
+ if (XGetWindowAttributes(ecore_x_display_get(), ee->prop.window,
+ &at))
+ {
+ einfo->info.visual = at.visual;
+ einfo->info.colormap = at.colormap;
+ einfo->info.depth = at.depth;
+ einfo->info.destination_alpha = 1;
+ }
+# endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
+ }
+ else
+ {
+# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
+ xcb_screen_t *screen;
+
+ screen = ecore_x_default_screen_get();
+ einfo->info.visual = xcb_visualtype_get(screen, screen->root_visual);
+ einfo->info.colormap = screen->default_colormap;
+ einfo->info.depth = screen->root_depth;
+#else
+ einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen);
+ einfo->info.colormap = DefaultColormap(ecore_x_display_get(), screen);
+ einfo->info.depth = DefaultDepth(ecore_x_display_get(), screen);
+# endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
+ einfo->info.destination_alpha = 0;
+ }
+ einfo->info.rotation = 0;
+ einfo->info.debug = redraw_debug;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
+ ecore_evas_free(ee);
+ return NULL;
+ }
+ }
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+
+ ee->engine.func->fn_render = _ecore_evas_x_render;
+ _ecore_evas_register(ee);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ return ee;
+}
+#else
+EAPI Ecore_Evas *
+ecore_evas_software_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
+ int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
+{
+ return NULL;
+}
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+EAPI Ecore_X_Window
+ecore_evas_software_x11_window_get(const Ecore_Evas *ee)
+{
+ return (Ecore_X_Window) ecore_evas_window_get(ee);
+}
+#else
+EAPI Ecore_X_Window
+ecore_evas_software_x11_window_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+EAPI void
+ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on)
+{
+ ee->engine.x.direct_resize = on;
+ if (ee->prop.avoid_damage)
+ {
+ if (ee->engine.x.direct_resize)
+ {
+/* turn this off for now
+ ee->engine.x.using_bg_pixmap = 1;
+ ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
+ */
+ }
+ else
+ {
+/* turn this off too- bg pixmap is controlled by avoid damage directly
+ ee->engine.x.using_bg_pixmap = 0;
+ ecore_x_window_pixmap_set(ee->prop.window, 0);
+ ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
+ */
+ }
+ }
+}
+#else
+EAPI void
+ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
+{
+}
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+EAPI int
+ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee)
+{
+ return ee->engine.x.direct_resize;
+}
+#else
+EAPI int
+ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
+EAPI void
+ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
+{
+ Ecore_X_Window *winp;
+
+ winp = malloc(sizeof(Ecore_X_Window));
+ if (winp)
+ {
+ *winp = win;
+ ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
+ ecore_x_input_multi_select(win);
+ ecore_event_window_register(win, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ }
+}
+#else
+EAPI void
+ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
+{
+}
+#endif
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+EAPI Ecore_Evas *
+ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h)
+{
+ return ecore_evas_gl_x11_options_new(disp_name, parent, x, y, w, h, NULL);
+}
+EAPI Ecore_Evas *
+ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h, const int *opt)
+{
+# ifdef HAVE_ECORE_X_XCB
+ Ecore_Evas *ee = NULL;
+# else
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("gl_x11");
+ if (!rmethod) return NULL;
+ if (!ecore_x_init(disp_name)) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_x_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
+
+ ee->driver = "opengl_x11";
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = w;
+ ee->h = h;
+ ee->req.x = ee->x;
+ ee->req.y = ee->y;
+ ee->req.w = ee->w;
+ ee->req.h = ee->h;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+ ee->prop.request_pos = 0;
+ ee->prop.sticky = 0;
+ ee->engine.x.state.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ if (parent == 0) parent = DefaultRootWindow(ecore_x_display_get());
+ ee->engine.x.win_root = parent;
+
+ if (ee->engine.x.win_root != 0)
+ {
+ ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
+ /* FIXME: round trip in ecore_x_window_argb_get */
+ if (ecore_x_window_argb_get(ee->engine.x.win_root))
+ {
+ ee->prop.window = _ecore_evas_x_gl_window_new
+ (ee, ee->engine.x.win_root, x, y, w, h, 0, 1, opt);
+ }
+ else
+ ee->prop.window = _ecore_evas_x_gl_window_new
+ (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
+ }
+ else
+ ee->prop.window = _ecore_evas_x_gl_window_new
+ (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
+ if (!ee->prop.window)
+ {
+ ecore_evas_free(ee);
+ return NULL;
+ }
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+// putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+
+ ee->engine.func->fn_render = _ecore_evas_x_render;
+ _ecore_evas_register(ee);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+# endif /* HAVE_ECORE_X_XCB */
+
+ return ee;
+}
+#else
+EAPI Ecore_Evas *
+ecore_evas_gl_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
+ int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
+{
+ return NULL;
+}
+EAPI Ecore_Evas *
+ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h, const int *opt)
+{
+ return NULL;
+}
+#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+EAPI Ecore_X_Window
+ecore_evas_gl_x11_window_get(const Ecore_Evas *ee)
+{
+ return (Ecore_X_Window) ecore_evas_window_get(ee);
+}
+#else
+EAPI Ecore_X_Window
+ecore_evas_gl_x11_window_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+EAPI void
+ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on)
+{
+ ee->engine.x.direct_resize = on;
+}
+#else
+EAPI void
+ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
+{
+}
+#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+EAPI int
+ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee)
+{
+ return ee->engine.x.direct_resize;
+}
+#else
+EAPI int
+ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+EAPI void
+ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
+{
+ ecore_evas_software_x11_extra_event_window_add(ee, win);
+}
+#else
+EAPI void
+ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
+{
+}
+#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#ifdef BUILD_ECORE_EVAS_OPENGL_X11
+EAPI void
+ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e))
+{
+ Evas_Engine_Info_GL_X11 *einfo;
+
+ if (!(!strcmp(ee->driver, "opengl_x11"))) return;
+
+ einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+ einfo->callback.pre_swap = pre_cb;
+ einfo->callback.pre_swap = post_cb;
+ einfo->callback.data = data;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+ }
+ }
+}
+#else
+EAPI void
+ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e))
+{
+ return;
+}
+#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+EAPI Ecore_Evas *
+ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h)
+{
+ Evas_Engine_Info_XRender_X11 *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+
+ rmethod = evas_render_method_lookup("xrender_x11");
+ if (!rmethod) return NULL;
+ if (!ecore_x_init(disp_name)) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_x_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
+
+ ee->driver = "xrender_x11";
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = w;
+ ee->h = h;
+ ee->req.x = ee->x;
+ ee->req.y = ee->y;
+ ee->req.w = ee->w;
+ ee->req.h = ee->h;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+ ee->prop.request_pos = 0;
+ ee->prop.sticky = 0;
+ ee->engine.x.state.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.x.win_root = parent;
+ ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+// putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+ einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
+ if (einfo)
+ {
+# ifdef BUILD_ECORE_EVAS_XRENDER_XCB
+ xcb_screen_iterator_t iter;
+ xcb_screen_t *screen;
+
+ /* FIXME: this is inefficient as its a round trip */
+ screen = ecore_x_default_screen_get();
+ iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
+ if (iter.rem > 1)
+ {
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+ Ecore_X_Window *roots;
+ int num;
+ uint8_t i;
+
+ num = 0;
+ cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
+
+ if (reply)
+ {
+ for (i = 0; i < num; xcb_screen_next (&iter), i++)
+ {
+ if (reply->root == roots[i])
+ {
+ screen = iter.data;
+ break;
+ }
+ }
+ free(reply);
+ }
+ free(roots);
+ }
+ else
+ {
+ reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
+ if (reply) free(reply);
+ }
+ }
+ einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XCB;
+ einfo->info.connection = ecore_x_connection_get();
+ einfo->info.screen = screen;
+ einfo->info.visual = screen->root_visual;
+# elif BUILD_ECORE_EVAS_XRENDER_X11
+ int screen;
+
+ /* FIXME: this is inefficient as its a round trip */
+ screen = DefaultScreen(ecore_x_display_get());
+ if (ScreenCount(ecore_x_display_get()) > 1)
+ {
+ Ecore_X_Window *roots;
+ int num, i;
+
+ num = 0;
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ XWindowAttributes at;
+
+ if (XGetWindowAttributes(ecore_x_display_get(),
+ parent, &at))
+ {
+ for (i = 0; i < num; i++)
+ {
+ if (at.root == roots[i])
+ {
+ screen = i;
+ break;
+ }
+ }
+ }
+ free(roots);
+ }
+ }
+ einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XLIB;
+ einfo->info.connection = ecore_x_display_get();
+ einfo->info.screen = NULL;
+ einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen);
+# endif /* BUILD_ECORE_EVAS_XRENDER_(XCB|X11) */
+ einfo->info.drawable = ee->prop.window;
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
+ ecore_evas_free(ee);
+ return NULL;
+ }
+ }
+
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+
+ ee->engine.func->fn_render = _ecore_evas_x_render;
+ _ecore_evas_register(ee);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ return ee;
+}
+#else
+EAPI Ecore_Evas *
+ecore_evas_xrender_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
+ int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
+{
+ return NULL;
+}
+#endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+EAPI Ecore_X_Window
+ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee)
+{
+ return (Ecore_X_Window) ecore_evas_window_get(ee);
+}
+#else
+EAPI Ecore_X_Window
+ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+EAPI void
+ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, int on)
+{
+ ee->engine.x.direct_resize = on;
+}
+#else
+EAPI void
+ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
+{
+}
+#endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+EAPI int
+ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee)
+{
+ return ee->engine.x.direct_resize;
+}
+#else
+EAPI int
+ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
+EAPI void
+ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
+{
+ ecore_evas_software_x11_extra_event_window_add(ee, win);
+}
+#else
+EAPI void
+ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
+{
+}
+#endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+EAPI Ecore_Evas *
+ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent,
+ int x, int y, int w, int h)
+{
+ Evas_Engine_Info_Software_16_X11 *einfo;
+ Ecore_Evas *ee;
+ int rmethod;
+ static int redraw_debug = -1;
+
+ rmethod = evas_render_method_lookup("software_16_x11");
+ if (!rmethod) return NULL;
+ if (!ecore_x_init(disp_name)) return NULL;
+ ee = calloc(1, sizeof(Ecore_Evas));
+ if (!ee) return NULL;
+
+ ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+ _ecore_evas_x_init();
+
+ ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
+
+ ee->driver = "software_16_x11";
+ if (disp_name) ee->name = strdup(disp_name);
+
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ee->x = x;
+ ee->y = y;
+ ee->w = w;
+ ee->h = h;
+ ee->req.x = ee->x;
+ ee->req.y = ee->y;
+ ee->req.w = ee->w;
+ ee->req.h = ee->h;
+
+ ee->prop.max.w = 32767;
+ ee->prop.max.h = 32767;
+ ee->prop.layer = 4;
+ ee->prop.request_pos = 0;
+ ee->prop.sticky = 0;
+ ee->engine.x.state.sticky = 0;
+
+ /* init evas here */
+ ee->evas = evas_new();
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
+ evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
+ evas_data_attach_set(ee->evas, ee);
+ evas_output_method_set(ee->evas, rmethod);
+ evas_output_size_set(ee->evas, w, h);
+ evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+ ee->engine.x.win_root = parent;
+ if (parent != 0)
+ {
+ /* FIXME: round trip in ecore_x_window_argb_get */
+ if (ecore_x_window_argb_get(parent))
+ {
+ ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
+ }
+ else
+ ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
+ }
+ else
+ ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
+ if (getenv("DESKTOP_STARTUP_ID"))
+ {
+ ecore_x_netwm_startup_id_set(ee->prop.window,
+ getenv("DESKTOP_STARTUP_ID"));
+ /* NB: on linux this may simply empty the env as opposed to completely
+ * unset it to being empty - unsure as solartis libc crashes looking
+ * for the '=' char */
+// putenv((char*)"DESKTOP_STARTUP_ID=");
+ }
+ einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
+
+ if (einfo)
+ {
+ if (ScreenCount(ecore_x_display_get()) > 1)
+ {
+ Ecore_X_Window *roots;
+ int num, i;
+
+ num = 0;
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ XWindowAttributes at;
+
+ if (XGetWindowAttributes(ecore_x_display_get(),
+ parent, &at))
+ {
+ for (i = 0; i < num; i++)
+ {
+ if (at.root == roots[i])
+ break;
+ }
+ }
+ free(roots);
+ }
+ }
+
+ if (redraw_debug < 0)
+ {
+ if (getenv("REDRAW_DEBUG"))
+ redraw_debug = atoi(getenv("REDRAW_DEBUG"));
+ else
+ redraw_debug = 0;
+ }
+ einfo->info.display = ecore_x_display_get();
+ einfo->info.drawable = ee->prop.window;
+
+ if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+ {
+ WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
+ ecore_evas_free(ee);
+ return NULL;
+ }
+ }
+
+ ecore_x_icccm_hints_set(ee->prop.window,
+ 1 /* accepts_focus */,
+ ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
+ 0 /* icon_pixmap */,
+ 0 /* icon_mask */,
+ 0 /* icon_window */,
+ 0 /* window_group */,
+ 0 /* is_urgent */);
+
+ ee->engine.func->fn_render = _ecore_evas_x_render;
+ _ecore_evas_register(ee);
+ ecore_x_input_multi_select(ee->prop.window);
+ ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ return ee;
+}
+#else
+EAPI Ecore_Evas *
+ecore_evas_software_x11_16_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
+ int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
+{
+ return NULL;
+}
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+EAPI Ecore_X_Window
+ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee)
+{
+ return (Ecore_X_Window) ecore_evas_window_get(ee);
+}
+#else
+EAPI Ecore_X_Window
+ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+EAPI void
+ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee, int on)
+{
+ ee->engine.x.direct_resize = on;
+ if (ee->prop.avoid_damage)
+ {
+ if (ee->engine.x.direct_resize)
+ {
+/* turn this off for now
+ ee->engine.x.using_bg_pixmap = 1;
+ ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
+ */
+ }
+ else
+ {
+/* turn this off too- bg pixmap is controlled by avoid damage directly
+ ee->engine.x.using_bg_pixmap = 0;
+ ecore_x_window_pixmap_set(ee->prop.window, 0);
+ ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
+ */
+ }
+ }
+}
+#else
+EAPI void
+ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
+{
+}
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+EAPI int
+ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee)
+{
+ return ee->engine.x.direct_resize;
+}
+#else
+EAPI int
+ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
+{
+ return 0;
+}
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
+EAPI void
+ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
+{
+ Ecore_X_Window *winp;
+
+ winp = malloc(sizeof(Ecore_X_Window));
+ if (winp)
+ {
+ *winp = win;
+ ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
+ ecore_x_input_multi_select(win);
+ ecore_event_window_register(win, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
+ }
+}
+#else
+EAPI void
+ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
+{
+}
+#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_fb.la
--- /dev/null
+#ifndef _ECORE_FB_H
+#define _ECORE_FB_H
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file
+ * @brief Ecore frame buffer system functions.
+ */
+
+/* FIXME:
+ * maybe a new module?
+ * - code to get battery info
+ * - code to get thermal info
+ * ecore evas fb isnt good enough for weird things, like multiple fb's, same happens here.
+ * backlight support using new kernel interface
+ * absolute axis
+ * joystick
+ * ecore_fb_li_device_close_all ? or a shutdown of the subsystem?
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _Ecore_Fb_Input_Device Ecore_Fb_Input_Device; /* an input device handler */
+
+/* device capabilities */
+enum _Ecore_Fb_Input_Device_Cap
+{
+ ECORE_FB_INPUT_DEVICE_CAP_NONE = 0x00000000,
+ ECORE_FB_INPUT_DEVICE_CAP_RELATIVE = 0x00000001,
+ ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE = 0x00000002,
+ ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS = 0x00000004
+};
+typedef enum _Ecore_Fb_Input_Device_Cap Ecore_Fb_Input_Device_Cap;
+
+EAPI extern int ECORE_FB_EVENT_KEY_DOWN; /**< FB Key Down event */
+EAPI extern int ECORE_FB_EVENT_KEY_UP; /**< FB Key Up event */
+EAPI extern int ECORE_FB_EVENT_MOUSE_BUTTON_DOWN; /**< FB Mouse Down event */
+EAPI extern int ECORE_FB_EVENT_MOUSE_BUTTON_UP; /**< FB Mouse Up event */
+EAPI extern int ECORE_FB_EVENT_MOUSE_MOVE; /**< FB Mouse Move event */
+EAPI extern int ECORE_FB_EVENT_MOUSE_WHEEL; /**< FB Mouse Wheel event */
+
+typedef struct _Ecore_Fb_Event_Key_Down Ecore_Fb_Event_Key_Down; /**< FB Key Down event */
+typedef struct _Ecore_Fb_Event_Key_Up Ecore_Fb_Event_Key_Up; /**< FB Key Up event */
+typedef struct _Ecore_Fb_Event_Mouse_Button_Down Ecore_Fb_Event_Mouse_Button_Down; /**< FB Mouse Down event */
+typedef struct _Ecore_Fb_Event_Mouse_Button_Up Ecore_Fb_Event_Mouse_Button_Up; /**< FB Mouse Up event */
+typedef struct _Ecore_Fb_Event_Mouse_Move Ecore_Fb_Event_Mouse_Move; /**< FB Mouse Move event */
+typedef struct _Ecore_Fb_Event_Mouse_Wheel Ecore_Fb_Event_Mouse_Wheel; /**< FB Mouse Wheel event */
+
+struct _Ecore_Fb_Event_Key_Down /** FB Key Down event */
+{
+ Ecore_Fb_Input_Device *dev; /**< The device associated with the event */
+ char *keyname; /**< The name of the key that was pressed */
+ char *keysymbol; /**< The logical symbol of the key that was pressed */
+ char *key_compose; /**< The UTF-8 string conversion if any */
+};
+
+struct _Ecore_Fb_Event_Key_Up /** FB Key Up event */
+{
+ Ecore_Fb_Input_Device *dev; /**< The device associated with the event */
+ char *keyname; /**< The name of the key that was released */
+ char *keysymbol; /**< The logical symbol of the key that was pressed */
+ char *key_compose; /**< The UTF-8 string conversion if any */
+};
+
+struct _Ecore_Fb_Event_Mouse_Button_Down /** FB Mouse Down event */
+{
+ Ecore_Fb_Input_Device *dev; /**< The device associated with the event */
+ int button; /**< Mouse button that was pressed (1 - 32) */
+ int x; /**< Mouse co-ordinates when mouse button was pressed */
+ int y; /**< Mouse co-ordinates when mouse button was pressed */
+ int double_click : 1; /**< Set if click was a double click */
+ int triple_click : 1; /**< Set if click was a triple click */
+};
+
+struct _Ecore_Fb_Event_Mouse_Button_Up /** FB Mouse Up event */
+{
+ Ecore_Fb_Input_Device *dev; /**< The device associated with the event */
+ int button; /**< Mouse button that was released (1 - 32) */
+ int x; /**< Mouse co-ordinates when mouse button was raised */
+ int y; /**< Mouse co-ordinates when mouse button was raised */
+};
+
+struct _Ecore_Fb_Event_Mouse_Move /** FB Mouse Move event */
+{
+ Ecore_Fb_Input_Device *dev; /**< The device associated with the event */
+ int x; /**< Mouse co-ordinates where the mouse cursor moved to */
+ int y; /**< Mouse co-ordinates where the mouse cursor moved to */
+};
+
+struct _Ecore_Fb_Event_Mouse_Wheel /** FB Mouse Wheel event */
+{
+ Ecore_Fb_Input_Device *dev;
+ int x,y;
+ int direction; /* 0 = vertical, 1 = horizontal */
+ int wheel; /* value 1 (left/up), -1 (right/down) */
+};
+
+/* ecore_fb_vt.c */
+EAPI void ecore_fb_callback_gain_set(void (*func) (void *data), void *data);
+EAPI void ecore_fb_callback_lose_set(void (*func) (void *data), void *data);
+/* ecore_fb_li.c */
+EAPI Ecore_Fb_Input_Device *ecore_fb_input_device_open(const char *dev);
+EAPI void ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev);
+EAPI void ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, int listen);
+EAPI const char *ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev);
+EAPI Ecore_Fb_Input_Device_Cap ecore_fb_input_device_cap_get(Ecore_Fb_Input_Device *dev);
+EAPI void ecore_fb_input_device_axis_size_set(Ecore_Fb_Input_Device *dev, int w, int h);
+EAPI void ecore_fb_input_threshold_click_set(Ecore_Fb_Input_Device *dev, double threshold);
+EAPI double ecore_fb_input_threshold_click_get(Ecore_Fb_Input_Device *dev);
+/* ecore_fb.c */
+EAPI int ecore_fb_init(const char *name);
+EAPI int ecore_fb_shutdown(void);
+EAPI void ecore_fb_size_get(int *w, int *h);
+
+EAPI void ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap);
+EAPI void ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore \
+@TSLIB_CFLAGS@ \
+@EINA_CFLAGS@
+
+if BUILD_ECORE_FB
+
+lib_LTLIBRARIES = libecore_fb.la
+include_HEADERS = \
+Ecore_Fb.h
+
+libecore_fb_la_SOURCES = \
+ecore_fb.c \
+ecore_fb_vt.c \
+ecore_fb_li.c \
+ecore_fb_ts.c
+# deprecated sources (might not compile):
+# ecore_fb_kbd.c
+# ecore_fb_ps2.c
+
+libecore_fb_la_LIBADD = \
+@TSLIB_LIBS@ \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@EINA_LIBS@
+
+libecore_fb_la_LDFLAGS = -version-info @version_info@ @ecore_fb_release_info@
+
+endif
+
+EXTRA_DIST = \
+ecore_fb_private.h \
+ecore_fb_keytable.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+static void _ecore_fb_size_get(int *w, int *h);
+
+EAPI int ECORE_FB_EVENT_KEY_DOWN = 0;
+EAPI int ECORE_FB_EVENT_KEY_UP = 0;
+EAPI int ECORE_FB_EVENT_MOUSE_BUTTON_DOWN = 0;
+EAPI int ECORE_FB_EVENT_MOUSE_BUTTON_UP = 0;
+EAPI int ECORE_FB_EVENT_MOUSE_MOVE = 0;
+EAPI int ECORE_FB_EVENT_MOUSE_WHEEL = 0;
+
+static int _ecore_fb_init_count = 0;
+static int _ecore_fb_console_w = 0;
+static int _ecore_fb_console_h = 0;
+
+static double _ecore_fb_double_click_time = 0.25;
+
+
+/**
+ * @defgroup Ecore_FB_Library_Group Framebuffer Library Functions
+ *
+ * Functions used to set up and shut down the Ecore_Framebuffer functions.
+ */
+
+/**
+ * Sets up the Ecore_Fb library.
+ * @param name device target name
+ * @return @c 0 on failure. Otherwise, the number of times the library has
+ * been initialised without being shut down.
+ * @ingroup Ecore_FB_Library_Group
+ */
+EAPI int
+ecore_fb_init(const char *name __UNUSED__)
+{
+ if (++_ecore_fb_init_count != 1)
+ return _ecore_fb_init_count;
+
+ if (!ecore_fb_vt_init())
+ return --_ecore_fb_init_count;
+
+ ECORE_FB_EVENT_KEY_DOWN = ecore_event_type_new();
+ ECORE_FB_EVENT_KEY_UP = ecore_event_type_new();
+ ECORE_FB_EVENT_MOUSE_BUTTON_DOWN = ecore_event_type_new();
+ ECORE_FB_EVENT_MOUSE_BUTTON_UP = ecore_event_type_new();
+ ECORE_FB_EVENT_MOUSE_MOVE = ecore_event_type_new();
+ ECORE_FB_EVENT_MOUSE_WHEEL = ecore_event_type_new();
+ _ecore_fb_size_get(&_ecore_fb_console_w, &_ecore_fb_console_h);
+
+ return _ecore_fb_init_count;
+}
+
+/**
+ * Shuts down the Ecore_Fb library.
+ * @return @c The number of times the system has been initialised without
+ * being shut down.
+ * @ingroup Ecore_FB_Library_Group
+ */
+EAPI int
+ecore_fb_shutdown(void)
+{
+ if (--_ecore_fb_init_count != 0)
+ return _ecore_fb_init_count;
+
+ ecore_fb_vt_shutdown();
+
+ return _ecore_fb_init_count;
+}
+
+
+/**
+ * Retrieves the width and height of the current frame buffer in pixels.
+ * @param w Pointer to an integer in which to store the width.
+ * @param h Pointer to an interge in which to store the height.
+ */
+EAPI void
+ecore_fb_size_get(int *w, int *h)
+{
+ if (w) *w = _ecore_fb_console_w;
+ if (h) *h = _ecore_fb_console_h;
+}
+
+static void
+_ecore_fb_size_get(int *w, int *h)
+{
+ struct fb_var_screeninfo fb_var;
+ int fb;
+
+ fb = open("/dev/fb0", O_RDWR);
+ if (fb < 0)
+ {
+ if (w) *w = 0;
+ if (h) *h = 0;
+ return;
+ }
+ if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1)
+ {
+ if (w) *w = 0;
+ if (h) *h = 0;
+ return;
+ }
+ close(fb);
+ if (w) *w = fb_var.xres;
+ if (h) *h = fb_var.yres;
+}
--- /dev/null
+static void _ecore_fb_event_free_key_down(void *data, void *ev);
+static void _ecore_fb_event_free_key_up(void *data, void *ev);
+
+static const char *_ecore_fb_kbd_syms[128 * 6] =
+{
+#include "ecore_fb_keytable.h"
+};
+
+static const char *_ecore_fb_btn_syms[128] =
+{
+ "0x00",
+ "Escape",
+ "F1",
+ "F2",
+ "F3",
+ "F4",
+ "Up",
+ "Right",
+ "Left",
+ "Down",
+ "Return",
+ "0x1b",
+ "0x1c",
+ "0x1d",
+ "0x1e",
+ "0x1f",
+ "0x20",
+ "0x21",
+ "0x22",
+ "0x23",
+ "0x24",
+ "0x25",
+ "0x26",
+ "0x27",
+ "0x28",
+ "0x29",
+ "0x2a",
+ "0x2b",
+ "0x2c",
+ "0x2d",
+ "0x2e",
+ "0x2f",
+ "0x30",
+ "0x31",
+ "0x32",
+ "0x33",
+ "0x34",
+ "0x35",
+ "0x36",
+ "0x37",
+ "0x38",
+ "0x39",
+ "0x3a",
+ "0x3b",
+ "0x3c",
+ "0x3d",
+ "0x3e",
+ "0x3f",
+ "0x40",
+ "0x41",
+ "0x42",
+ "0x43",
+ "0x44",
+ "0x45",
+ "0x46",
+ "0x47",
+ "0x48",
+ "0x49",
+ "0x4a",
+ "0x4b",
+ "0x4c",
+ "0x4d",
+ "0x4e",
+ "0x4f",
+ "0x50",
+ "0x51",
+ "0x52",
+ "0x53",
+ "0x54",
+ "0x55",
+ "0x56",
+ "0x57",
+ "0x58",
+ "0x59",
+ "0x5a",
+ "0x5b",
+ "0x5c",
+ "0x5d",
+ "0x5e",
+ "0x5f",
+ "0x60",
+ "0x61",
+ "0x62",
+ "0x63",
+ "0x64",
+ "0x65",
+ "0x66",
+ "0x67",
+ "0x68",
+ "0x69",
+ "0x6a",
+ "0x6b",
+ "0x6c",
+ "0x6d",
+ "0x6e",
+ "0x6f",
+ "0x70",
+ "0x71",
+ "0x72",
+ "0x73",
+ "0x74",
+ "0x75",
+ "0x76",
+ "0x77",
+ "0x78",
+ "0x79",
+ "0x7a",
+ "0x7b",
+ "0x7c",
+ "0x7d",
+ "0x7e",
+ "0x7f"
+};
+static int _ecore_fb_kbd_fd = 0;
+static int _ecore_fb_ctrl = 0;
+static int _ecore_fb_alt = 0;
+static int _ecore_fb_shift = 0;
+static int _ecore_fb_lock = 0;
+
+static Ecore_Fd_Handler *_ecore_fb_kbd_fd_handler_handle = NULL;
+static int _ecore_fb_kbd_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+
+static void
+_ecore_fb_event_free_key_down(void *data __UNUSED__, void *ev)
+{
+ Ecore_Fb_Event_Key_Up *e;
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_fb_event_free_key_up(void *data __UNUSED__, void *ev)
+{
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static int
+_ecore_fb_kbd_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ int v = 0;
+
+ do
+ {
+ unsigned char buf;
+
+ v = read(_ecore_fb_kbd_fd, &buf, 1);
+ if (v < 0) return 1;
+ if (v < 1) return 1;
+ if (!(buf & 0x80))
+ {
+ /* DOWN */
+ int vt_switch = -1;
+ Ecore_Fb_Event_Key_Down *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Key_Down));
+ if (!e) goto retry;
+ if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd)
+ {
+ int add = 0;
+
+ if (_ecore_fb_shift) add = 1;
+ else if (_ecore_fb_lock) add = 2;
+ e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 6]);
+ e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + add]);
+ e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + 3 + add]);
+ }
+ else
+ e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]);
+ if (!e->keyname)
+ {
+ free(e);
+ goto retry;
+ }
+ ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, e, _ecore_fb_event_free_key_down, NULL);
+ if (!strcmp(e->keyname, "Control_L"))
+ _ecore_fb_ctrl++;
+ else if (!strcmp(e->keyname, "Control_R"))
+ _ecore_fb_ctrl++;
+ else if (!strcmp(e->keyname, "Alt_L"))
+ _ecore_fb_alt++;
+ else if (!strcmp(e->keyname, "Alt_R"))
+ _ecore_fb_alt++;
+ else if (!strcmp(e->keyname, "Shift_L"))
+ _ecore_fb_shift++;
+ else if (!strcmp(e->keyname, "Shift_R"))
+ _ecore_fb_shift++;
+ else if (!strcmp(e->keyname, "Caps_Lock"))
+ _ecore_fb_lock++;
+ else if (!strcmp(e->keyname, "F1")) vt_switch = 0;
+ else if (!strcmp(e->keyname, "F2")) vt_switch = 1;
+ else if (!strcmp(e->keyname, "F3")) vt_switch = 2;
+ else if (!strcmp(e->keyname, "F4")) vt_switch = 3;
+ else if (!strcmp(e->keyname, "F5")) vt_switch = 4;
+ else if (!strcmp(e->keyname, "F6")) vt_switch = 5;
+ else if (!strcmp(e->keyname, "F7")) vt_switch = 6;
+ else if (!strcmp(e->keyname, "F8")) vt_switch = 7;
+ else if (!strcmp(e->keyname, "F9")) vt_switch = 8;
+ else if (!strcmp(e->keyname, "F10")) vt_switch = 9;
+ else if (!strcmp(e->keyname, "F11")) vt_switch = 10;
+ else if (!strcmp(e->keyname, "F12")) vt_switch = 11;
+ if (_ecore_fb_ctrl > 2) _ecore_fb_ctrl = 2;
+ if (_ecore_fb_alt > 2) _ecore_fb_alt = 2;
+ if ((vt_switch >= 0) &&
+ (_ecore_fb_ctrl) &&
+ (_ecore_fb_alt))
+ _ecore_fb_vt_switch(vt_switch);
+ }
+ else
+ {
+ /* UP */
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Key_Up));
+ if (!e) goto retry;
+ if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd)
+ {
+ int add = 0;
+
+ if (_ecore_fb_shift) add = 1;
+ else if (_ecore_fb_lock) add = 2;
+ e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 6]);
+ e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + add]);
+ e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + 3 + add]);
+ }
+ else
+ e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]);
+ if (!e->keyname)
+ {
+ free(e);
+ goto retry;
+ }
+ ecore_event_add(ECORE_FB_EVENT_KEY_UP, e, _ecore_fb_event_free_key_up, NULL);
+ if (!strcmp(e->keyname, "Control_L"))
+ _ecore_fb_ctrl--;
+ else if (!strcmp(e->keyname, "Control_R"))
+ _ecore_fb_ctrl--;
+ else if (!strcmp(e->keyname, "Alt_L"))
+ _ecore_fb_alt--;
+ else if (!strcmp(e->keyname, "Alt_R"))
+ _ecore_fb_alt--;
+ else if (!strcmp(e->keyname, "Shift_L"))
+ _ecore_fb_shift--;
+ else if (!strcmp(e->keyname, "Shift_R"))
+ _ecore_fb_shift--;
+ else if (!strcmp(e->keyname, "Caps_Lock"))
+ _ecore_fb_lock--;
+ if (_ecore_fb_ctrl < 0) _ecore_fb_ctrl = 0;
+ if (_ecore_fb_alt < 0) _ecore_fb_alt = 0;
+ if (_ecore_fb_shift < 0) _ecore_fb_shift = 0;
+ if (_ecore_fb_lock < 0) _ecore_fb_lock = 0;
+ }
+ retry:
+ ;
+ }
+ while (v > 0);
+ return 1;
+}
+
+int
+ecore_fb_kbd_init(void)
+{
+ int prev_flags;
+
+ prev_flags = fcntl(_ecore_fb_kbd_fd, F_GETFL);
+ fcntl(_ecore_fb_kbd_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_kbd_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_kbd_fd,
+ ECORE_FD_READ,
+ _ecore_fb_kbd_fd_handler, NULL,
+ NULL, NULL);
+ if(!_ecore_fb_kbd_fd_handler_handle) return 0;
+ return 1;
+}
+
+void
+ecore_fb_kbd_shutdown(void)
+{
+ if (_ecore_fb_kbd_fd >= 0) close(_ecore_fb_kbd_fd);
+ if (_ecore_fb_kbd_fd_handler_handle)
+ ecore_main_fd_handler_del(_ecore_fb_kbd_fd_handler_handle);
+ _ecore_fb_kbd_fd = 0;
+ _ecore_fb_kbd_fd_handler_handle = NULL;
+ _ecore_fb_ctrl = 0;
+ _ecore_fb_lock = 0;
+ _ecore_fb_shift = 0;
+ _ecore_fb_alt = 0;
+}
--- /dev/null
+/* this table was taken from ecore_fb, is the default en layout */
+ "0x00", "0x00", "0x00", /**/"", "", "",/***/
+ "Escape", "Escape", "Escape", /**/"", "", "",/***/
+ "1", "exclam", "1", /**/"1", "!", "1",/***/
+ "2", "at", "2", /**/"2", "@", "2",/***/
+ "3", "numbersign", "3", /**/"3", "#", "3",/***/
+ "4", "dollar", "4", /**/"4", "$", "4",/***/
+ "5", "percent", "5", /**/"5", "%", "5",/***/
+ "6", "asciicircumm", "6", /**/"6", "^", "6",/***/
+ "7", "ampersand", "7", /**/"7", "&", "7",/***/
+ "8", "asterik", "8", /**/"8", "*", "8",/***/
+ "9", "parenleft", "9", /**/"9", "(", "9",/***/
+ "0", "parenright", "0", /**/"0", ")", "0",/***/
+ "minus", "underscore", "minus", /**/"-", "_", "-",/***/
+ "equal", "plus", "equal", /**/"=", "+", "=",/***/
+ "BackSpace", "BackSpace", "BackSpace", /**/"\010","\010","\010",/***/
+ "Tab", "ISO_Left_Tab", "Tab", /**/"\011","", "\011",/***/
+ "q", "Q", "Q", /**/"q", "Q", "Q",/***/
+ "w", "W", "W", /**/"w", "W", "W",/***/
+ "e", "E", "E", /**/"e", "E", "E",/***/
+ "r", "R", "R", /**/"r", "R", "R",/***/
+ "t", "T", "T", /**/"t", "T", "T",/***/
+ "y", "Y", "Y", /**/"y", "Y", "Y",/***/
+ "u", "U", "U", /**/"u", "U", "U",/***/
+ "i", "I", "I", /**/"i", "I", "I",/***/
+ "o", "O", "O", /**/"o", "O", "O",/***/
+ "p", "P", "P", /**/"p", "P", "P",/***/
+ "bracketleft", "braceleft", "bracketleft", /**/"[", "{", "[",/***/
+ "bracketright", "braceright", "bracketright", /**/"]", "}", "]",/***/
+ "Return", "Return", "Return", /**/"\015","\015","\015",/***/
+ "Control_L", "Control_L", "Control_L", /**/"", "", "",/***/
+ "a", "A", "A", /**/"a", "A", "A",/***/
+ "s", "S", "S", /**/"s", "S", "S",/***/
+ "d", "D", "D", /**/"d", "D", "D",/***/
+ "f", "F", "F", /**/"f", "F", "F",/***/
+ "g", "G", "G", /**/"g", "G", "G",/***/
+ "h", "h", "H", /**/"h", "H", "H",/***/
+ "j", "J", "J", /**/"j", "J", "J",/***/
+ "k", "K", "K", /**/"k", "K", "K",/***/
+ "l", "L", "L", /**/"l", "L", "L",/***/
+ "semicolon", "colon", "semicolon", /**/";", ":", ";",/***/
+ "apostrophe", "quotedbl", "apostrophe", /**/"'", "\"", "'",/***/
+ "grave", "asciitilde", "grave", /**/"`", "~", "`",/***/
+ "Shift_L", "Shift_L", "Shift_L", /**/"", "", "",/***/
+ "backslash", "bar", "backslash", /**/"\\", "|", "\\",/***/
+ "z", "Z", "Z", /**/"z", "Z", "Z",/***/
+ "x", "X", "X", /**/"x", "X", "X",/***/
+ "c", "C", "C", /**/"c", "C", "C",/***/
+ "v", "V", "V", /**/"v", "V", "V",/***/
+ "b", "B", "B", /**/"b", "B", "B",/***/
+ "n", "N", "N", /**/"n", "N", "N",/***/
+ "m", "M", "M", /**/"m", "M", "M",/***/
+ "comma", "less", "comma", /**/",", "<", ",",/***/
+ "period", "greater", "period", /**/".", ">", ".",/***/
+ "slash", "question", "slash", /**/"/", "?", "/",/***/
+ "Shift_R", "Shift_R", "Shift_R", /**/"", "", "",/***/
+ "KP_Multiply", "KP_Multiply", "KP_Multiply", /**/"", "*", "",/***/
+ "Alt_L", "Alt_L", "Alt_L", /**/"", "", "",/***/
+ "space", "space", "space", /**/" ", " ", " ",/***/
+ "Caps_Lock", "Caps_Lock", "Caps_Lock", /**/"", "", "",/***/
+ "F1", "F1", "F1", /**/"", "", "",/***/
+ "F2", "F2", "F2", /**/"", "", "",/***/
+ "F3", "F3", "F3", /**/"", "", "",/***/
+ "F4", "F4", "F4", /**/"", "", "",/***/
+ "F5", "F5", "F5", /**/"", "", "",/***/
+ "F6", "F6", "F6", /**/"", "", "",/***/
+ "F7", "F7", "F7", /**/"", "", "",/***/
+ "F8", "F8", "F8", /**/"", "", "",/***/
+ "F9", "F9", "F9", /**/"", "", "",/***/
+ "F10", "F10", "F10", /**/"", "", "",/***/
+ "Num_Lock", "Num_Lock", "Num_Lock", /**/"", "", "",/***/
+ "Scroll_Lock", "Scroll_Lock", "Scroll_Lock", /**/"", "", "",/***/
+ "KP_Home", "KP_7", "KP_Home", /**/"", "7", "",/***/
+ "KP_Up", "KP_8", "KP_Up", /**/"", "8", "",/***/
+ "KP_Prior", "KP_9", "KP_Prior", /**/"", "9", "",/***/
+ "KP_Subtract", "KP_Subtract", "KP_Subtract", /**/"", "", "",/***/
+ "KP_Left", "KP_4", "KP_Left", /**/"", "4", "",/***/
+ "KP_Begin", "KP_5", "KP_Begin", /**/"", "5", "",/***/
+ "KP_Right", "KP_6", "KP_Right", /**/"", "6", "",/***/
+ "KP_Add", "KP_Add", "KP_Add", /**/"", "", "",/***/
+ "KP_End", "KP_1", "KP_End", /**/"", "1", "",/***/
+ "KP_Down", "KP_2", "KP_Down", /**/"", "2", "",/***/
+ "KP_Next", "KP_3", "KP_Next", /**/"", "3", "",/***/
+ "KP_Insert", "KP_0", "KP_Insert", /**/"", "0", "",/***/
+ "KP_Delete", "KP_Decimal", "KP_Delete", /**/"", ".", "",/***/
+ "0x54", "0x54", "0x54", /**/"", "", "",/***/
+ "0x55", "0x55", "0x55", /**/"", "", "",/***/
+ "0x56", "0x56", "0x56", /**/"", "", "",/***/
+ "F11", "F11", "F11", /**/"", "", "",/***/
+ "F12", "F12", "F12", /**/"", "", "",/***/
+ "0x59", "0x59", "0x59", /**/"", "", "",/***/
+ "0x5a", "0x5a", "0x5a", /**/"", "", "",/***/
+ "0x5b", "0x5b", "0x5b", /**/"", "", "",/***/
+ "0x5c", "0x5c", "0x5c", /**/"", "", "",/***/
+ "0x5d", "0x5d", "0x5d", /**/"", "", "",/***/
+ "0x5e", "0x5e", "0x5e", /**/"", "", "",/***/
+ "0x5f", "0x5f", "0x5f", /**/"", "", "",/***/
+ "KP_Enter", "KP_Enter", "KP_Enter", /**/"", "", "",/***/
+ "Control_R", "Control_R", "Control_R", /**/"", "", "",/***/
+ "KP_Divide", "KP_Divide", "KP_Divide", /**/"", "", "",/***/
+ "Print", "Print", "Print", /**/"", "", "",/***/
+ "Alt_R", "Alt_R", "Alt_R", /**/"", "", "",/***/
+ "0x65", "0x65", "0x65", /**/"", "", "",/***/
+ "Home", "Home", "Home", /**/"", "", "",/***/
+ "Up", "Up", "Up", /**/"", "", "",/***/
+ "Prior", "Prior", "Prior", /**/"", "", "",/***/
+ "Left", "Left", "Left", /**/"", "", "",/***/
+ "Right", "Right", "Right", /**/"", "", "",/***/
+ "End", "End", "End", /**/"", "", "",/***/
+ "Down", "Down", "Down", /**/"", "", "",/***/
+ "Next", "Next", "Next", /**/"", "", "",/***/
+ "Insert", "Insert", "Insert", /**/"", "", "",/***/
+ "Delete", "Delete", "Delete", /**/"\177","\177","\177",/***/
+ "0x70", "0x70", "0x70", /**/"", "", "",/***/
+ "0x71", "0x71", "0x71", /**/"", "", "",/***/
+ "0x72", "0x72", "0x72", /**/"", "", "",/***/
+ "0x73", "0x73", "0x73", /**/"", "", "",/***/
+ "0x74", "0x74", "0x74", /**/"", "", "",/***/
+ "0x75", "0x75", "0x75", /**/"", "", "",/***/
+ "0x76", "0x76", "0x76", /**/"", "", "",/***/
+ "Pause", "Pause", "Pause", /**/"", "", "",/***/
+ "0x78", "0x78", "0x78", /**/"", "", "",/***/
+ "0x79", "0x79", "0x79", /**/"", "", "",/***/
+ "0x7a", "0x7a", "0x7a", /**/"", "", "",/***/
+ "0x7b", "0x7b", "0x7b", /**/"", "", "",/***/
+ "0x7c", "0x7c", "0x7c", /**/"", "", "",/***/
+ "Super_L", "Super_L", "Super_L", /**/"", "", "",/***/
+ "Super_R", "Super_R", "Super_R", /**/"", "", "",/***/
+ "0x7f", "0x7f", "0x7f", /**/"", "", "" /***/
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+#define CLICK_THRESHOLD_DEFAULT 0.25
+
+static Eina_List *_ecore_fb_li_devices = NULL;
+
+static const char *_ecore_fb_li_kbd_syms[128 * 6] =
+{
+#include "ecore_fb_keytable.h"
+};
+
+/* Initial Copyright (C) Brad Hards (1999-2002),
+ * this function is used to tell if "bit" is set in "array"
+ * it selects a byte from the array, and does a boolean AND
+ * operation with a byte that only has the relevant bit set.
+ * eg. to check for the 12th bit, we do (array[1] & 1<<4).
+ * Moved to static inline in order to force compiler to otimized
+ * the unsued part away or force a link error if long has an unexpected
+ * size.
+ * - bigeasy
+ */
+extern int long_has_neither_32_nor_64_bits(void);
+static inline int test_bit(int bit, unsigned long *array)
+{
+ if (sizeof(long) == 4)
+ return array[bit / 32] & (1 << (bit % 32));
+
+ else if (sizeof(long) == 8)
+ return array[bit / 64] & (1 << (bit % 64));
+
+ else long_has_neither_32_nor_64_bits();
+}
+
+static void
+_ecore_fb_li_event_free_key_down(void *data, void *ev)
+{
+
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_fb_li_event_free_key_up(void *data, void *ev)
+{
+
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_fb_li_device_event_key(Ecore_Fb_Input_Device *dev, struct input_event *iev)
+{
+ if(!dev->listen)
+ return;
+
+ /* check for basic keyboard keys */
+ if(iev->code >= KEY_ESC && iev->code <= KEY_COMPOSE)
+ {
+ /* check the key table */
+ if(iev->value)
+ {
+ int offset = 0;
+ Ecore_Fb_Event_Key_Down *ev;
+
+ ev = calloc(1, sizeof(Ecore_Fb_Event_Key_Down));
+ if(dev->keyboard.shift) offset = 1;
+ else if(dev->keyboard.lock) offset = 2;
+ ev->keyname = strdup(_ecore_fb_li_kbd_syms[iev->code * 6]);
+
+ ev->keysymbol = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + offset]);
+ ev->key_compose = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + 3 + offset]);
+ ev->dev = dev;
+ ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, ev, _ecore_fb_li_event_free_key_down, NULL);
+ /* its a repeated key, dont increment */
+ if(iev->value == 2)
+ return;
+ if (!strcmp(ev->keyname, "Control_L"))
+ dev->keyboard.ctrl++;
+ else if (!strcmp(ev->keyname, "Control_R"))
+ dev->keyboard.ctrl++;
+ else if (!strcmp(ev->keyname, "Alt_L"))
+ dev->keyboard.alt++;
+ else if (!strcmp(ev->keyname, "Alt_R"))
+ dev->keyboard.alt++;
+ else if (!strcmp(ev->keyname, "Shift_L"))
+ dev->keyboard.shift++;
+ else if (!strcmp(ev->keyname, "Shift_R"))
+ dev->keyboard.shift++;
+ else if (!strcmp(ev->keyname, "Caps_Lock"))
+ dev->keyboard.lock++;
+ if (dev->keyboard.ctrl > 2) dev->keyboard.ctrl = 2;
+ if (dev->keyboard.alt > 2) dev->keyboard.alt = 2;
+ if (dev->keyboard.shift > 2) dev->keyboard.shift = 2;
+ if (dev->keyboard.lock > 1) dev->keyboard.lock = 1;
+ }
+ else
+ {
+ int offset = 0;
+ Ecore_Fb_Event_Key_Up *ev;
+
+ ev = calloc(1, sizeof(Ecore_Fb_Event_Key_Up));
+ if(dev->keyboard.shift) offset = 1;
+ else if(dev->keyboard.lock) offset = 2;
+ ev->keyname = strdup(_ecore_fb_li_kbd_syms[iev->code * 6]);
+
+ ev->keysymbol = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + offset]);
+ ev->key_compose = strdup(_ecore_fb_li_kbd_syms[(iev->code * 6) + 3 + offset]);
+ ev->dev = dev;
+ ecore_event_add(ECORE_FB_EVENT_KEY_UP, ev, _ecore_fb_li_event_free_key_up, NULL);
+ if (!strcmp(ev->keyname, "Control_L"))
+ dev->keyboard.ctrl--;
+ else if (!strcmp(ev->keyname, "Control_R"))
+ dev->keyboard.ctrl--;
+ else if (!strcmp(ev->keyname, "Alt_L"))
+ dev->keyboard.alt--;
+ else if (!strcmp(ev->keyname, "Alt_R"))
+ dev->keyboard.alt--;
+ else if (!strcmp(ev->keyname, "Shift_L"))
+ dev->keyboard.shift--;
+ else if (!strcmp(ev->keyname, "Shift_R"))
+ dev->keyboard.shift--;
+ else if (!strcmp(ev->keyname, "Caps_Lock"))
+ dev->keyboard.lock--;
+ if (dev->keyboard.ctrl < 0) dev->keyboard.ctrl = 0;
+ if (dev->keyboard.alt < 0) dev->keyboard.alt = 0;
+ if (dev->keyboard.shift < 0) dev->keyboard.shift = 0;
+ if (dev->keyboard.lock < 0) dev->keyboard.lock = 0;
+ }
+ }
+ /* check for mouse button events */
+ else if(iev->code >= BTN_MOUSE && iev->code < BTN_JOYSTICK)
+ {
+ int button;
+
+ button = ((iev->code & 0x00F) + 1);
+ if(iev->value)
+ {
+ Ecore_Fb_Event_Mouse_Button_Down *ev;
+ double current;
+
+ ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
+ ev->dev = dev;
+ ev->button = button;
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+
+ current = ecore_time_get();
+ if((current - dev->mouse.prev) <= dev->mouse.threshold)
+ {
+ ev->double_click = 1;
+ }
+ if((current - dev->mouse.last) <= (2 * dev->mouse.threshold))
+ {
+ ev->triple_click = 1;
+ /* reset */
+ dev->mouse.prev = 0;
+ dev->mouse.last = 0;
+ current = 0;
+ }
+ else
+ {
+ /* update values */
+ dev->mouse.last = dev->mouse.prev;
+ dev->mouse.prev = current;
+ }
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, ev, NULL ,NULL);
+ }
+ else
+ {
+ Ecore_Fb_Event_Mouse_Button_Up *ev;
+
+ ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Button_Up));
+ ev->dev = dev;
+ ev->button = button;
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, ev, NULL ,NULL);
+ }
+ }
+}
+
+static void
+_ecore_fb_li_device_event_rel(Ecore_Fb_Input_Device *dev, struct input_event *iev)
+{
+ if(!dev->listen)
+ return;
+ /* dispatch the button events if they are queued */
+ switch(iev->code)
+ {
+ case REL_X:
+ case REL_Y:
+ {
+ Ecore_Fb_Event_Mouse_Move *ev;
+ if(iev->code == REL_X)
+ {
+ dev->mouse.x += iev->value;
+ if(dev->mouse.x > dev->mouse.w - 1)
+ dev->mouse.x = dev->mouse.w;
+ else if(dev->mouse.x < 0)
+ dev->mouse.x = 0;
+ }
+ else
+ {
+ dev->mouse.y += iev->value;
+ if(dev->mouse.y > dev->mouse.h - 1)
+ dev->mouse.y = dev->mouse.h;
+ else if(dev->mouse.y < 0)
+ dev->mouse.y = 0;
+ }
+ ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Move));
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ ev->dev = dev;
+
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE,ev,NULL,NULL);
+ break;
+ }
+ case REL_WHEEL:
+ case REL_HWHEEL:
+ {
+ Ecore_Fb_Event_Mouse_Wheel *ev;
+ ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Wheel));
+
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ if(iev->code == REL_HWHEEL)
+ ev->direction = 1;
+ ev->wheel = iev->value;
+ ev->dev = dev;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void
+_ecore_fb_li_device_event_abs(Ecore_Fb_Input_Device *dev, struct input_event *iev)
+{
+ static int prev_pressure = 0;
+ int pressure;
+
+ if(!dev->listen)
+ return;
+ switch(iev->code)
+ {
+ case ABS_X:
+ if(dev->mouse.w != 0)
+ {
+ int tmp;
+
+ tmp = (int)((double)(iev->value - dev->mouse.min_w) / dev->mouse.rel_w);
+ if(tmp < 0)
+ dev->mouse.x = 0;
+ else if(tmp > dev->mouse.w)
+ dev->mouse.x = dev->mouse.w;
+ else
+ dev->mouse.x = tmp;
+ dev->mouse.event = ECORE_FB_EVENT_MOUSE_MOVE;
+ }
+ break;
+
+ case ABS_Y:
+ if(dev->mouse.h != 0)
+ {
+ int tmp;
+
+ tmp = (int)((double)(iev->value - dev->mouse.min_h) / dev->mouse.rel_h);
+ if(tmp < 0)
+ dev->mouse.y = 0;
+ else if(tmp > dev->mouse.h)
+ dev->mouse.y = dev->mouse.h;
+ else
+ dev->mouse.y = tmp;
+ dev->mouse.event = ECORE_FB_EVENT_MOUSE_MOVE;
+ }
+ break;
+
+ case ABS_PRESSURE:
+ pressure = iev->value;
+ if ((pressure) && (!prev_pressure))
+ {
+ /* DOWN: mouse is down, but was not now */
+ dev->mouse.event = ECORE_FB_EVENT_MOUSE_BUTTON_DOWN;
+ }
+ else if ((!pressure) && (prev_pressure))
+ {
+ /* UP: mouse was down, but is not now */
+ dev->mouse.event = ECORE_FB_EVENT_MOUSE_BUTTON_UP;
+ }
+ prev_pressure = pressure;
+ break;
+ }
+}
+
+static void
+_ecore_fb_li_device_event_syn(Ecore_Fb_Input_Device *dev, struct input_event *iev)
+{
+ if(!dev->listen)
+ return;
+
+ if(dev->mouse.event == ECORE_FB_EVENT_MOUSE_MOVE)
+ {
+ Ecore_Fb_Event_Mouse_Move *ev;
+ ev = calloc(1,sizeof(Ecore_Fb_Event_Mouse_Move));
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ ev->dev = dev;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, ev, NULL, NULL);
+ }
+ else if(dev->mouse.event == ECORE_FB_EVENT_MOUSE_BUTTON_DOWN)
+ {
+ Ecore_Fb_Event_Mouse_Button_Down *ev;
+ ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ ev->button = 1;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
+ }
+ else if(dev->mouse.event == ECORE_FB_EVENT_MOUSE_BUTTON_UP)
+ {
+ Ecore_Fb_Event_Mouse_Button_Up *ev;
+ ev = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ ev->button = 1;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
+ }
+}
+
+static int
+_ecore_fb_li_device_fd_callback(void *data, Ecore_Fd_Handler *fdh)
+{
+ Ecore_Fb_Input_Device *dev;
+ struct input_event ev[64];
+ int len;
+ int i;
+
+ dev = (Ecore_Fb_Input_Device*)data;
+ /* read up to 64 events at once */
+ len = read(dev->fd, &ev, sizeof(ev));
+ // printf("[ecore_fb_li_device:fd_callback] received %d data\n", len);
+ for(i = 0; i < len/sizeof(ev[0]); i++)
+ {
+ switch(ev[i].type)
+ {
+ case EV_SYN:
+ _ecore_fb_li_device_event_syn(dev, &ev[i]);
+ break;
+ case EV_ABS:
+ _ecore_fb_li_device_event_abs(dev, &ev[i]);
+ break;
+ case EV_REL:
+ _ecore_fb_li_device_event_rel(dev, &ev[i]);
+ break;
+ case EV_KEY:
+ _ecore_fb_li_device_event_key(dev, &ev[i]);
+ break;
+ default:
+ break;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Starts getting events from the input device
+ *
+ */
+EAPI void
+ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, int listen)
+{
+ if(!dev) return;
+ if((listen && dev->listen) || (!listen && !dev->listen)) return;
+ if(listen)
+ {
+ /* if the device already had a handler */
+ if(!dev->handler)
+ dev->handler = ecore_main_fd_handler_add(dev->fd, ECORE_FD_READ, _ecore_fb_li_device_fd_callback, dev, NULL, NULL);
+
+ }
+ dev->listen = listen;
+}
+
+#ifndef EV_CNT
+#define EV_CNT (EV_MAX+1)
+#endif
+
+/*
+ * Opens an input device
+ */
+EAPI Ecore_Fb_Input_Device *
+ecore_fb_input_device_open(const char *dev)
+{
+ Ecore_Fb_Input_Device *device;
+ unsigned long event_type_bitmask[EV_CNT / 32 + 1];
+ int event_type;
+ int fd;
+
+ if(!dev) return NULL;
+ device = calloc(1, sizeof(Ecore_Fb_Input_Device));
+ if(!device) return NULL;
+
+ if((fd = open(dev, O_RDONLY, O_NONBLOCK)) < 0)
+ {
+ fprintf(stderr, "[ecore_fb_li:device_open] %s %s", dev, strerror(errno));
+ goto error_open;
+ }
+ /* query capabilities */
+ if(ioctl(fd, EVIOCGBIT(0, EV_MAX), event_type_bitmask) < 0)
+ {
+ fprintf(stderr,"[ecore_fb_li:device_open] query capabilities %s %s", dev, strerror(errno));
+ goto error_caps;
+ }
+ /* query name */
+ device->info.name = calloc(256, sizeof(char));
+ if(ioctl(fd, EVIOCGNAME(sizeof(char) * 256), device->info.name) < 0)
+ {
+ fprintf(stderr, "[ecore_fb_li:device_open] get name %s %s", dev, strerror(errno));
+ strcpy(device->info.name, "Unknown");
+ }
+ device->fd = fd;
+ device->info.dev = strdup(dev);
+ /* common */
+ device->mouse.threshold = CLICK_THRESHOLD_DEFAULT;
+
+ /* set info */
+ for(event_type = 0; event_type < EV_MAX; event_type++)
+ {
+ if(!test_bit(event_type, event_type_bitmask))
+ continue;
+ switch(event_type)
+ {
+ case EV_SYN :
+ break;
+
+ case EV_KEY:
+ device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS;
+ break;
+
+ case EV_REL:
+ device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_RELATIVE;
+ break;
+
+ case EV_ABS:
+ device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE;
+ break;
+
+ case EV_MSC:
+ case EV_LED:
+ case EV_SND:
+ case EV_REP:
+ case EV_FF :
+ case EV_FF_STATUS:
+ case EV_PWR:
+ default:
+ break;
+ }
+ }
+ _ecore_fb_li_devices = eina_list_append(_ecore_fb_li_devices, device);
+ return device;
+
+ error_caps:
+ close(fd);
+ error_open:
+ free(device);
+ return NULL;
+
+}
+
+EAPI void
+ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev)
+{
+ /* close the fd */
+ close(dev->fd);
+ /* remove the element from the list */
+ _ecore_fb_li_devices = eina_list_remove(_ecore_fb_li_devices, dev);
+ free(dev);
+}
+
+
+/*
+ * If the device is a relative input device,
+ * we must set a width and height for it. If its
+ * absolute set the ioctl correctly, if not, unsupported
+ * device
+ */
+EAPI void
+ecore_fb_input_device_axis_size_set(Ecore_Fb_Input_Device *dev, int w, int h)
+{
+ if(!dev)
+ return;
+ if(w < 0 || h < 0)
+ return;
+ /* FIXME
+ * this code is for a touchscreen device,
+ * make it configurable (ABSOLUTE | RELATIVE)
+ */
+ if(dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE)
+ {
+ /* FIXME looks like some kernels dont include this struct */
+ struct input_absinfo abs_features;
+
+ ioctl(dev->fd, EVIOCGABS(ABS_X), &abs_features);
+ dev->mouse.min_w = abs_features.minimum;
+ dev->mouse.rel_w = (double)(abs_features.maximum - abs_features.minimum)/(double)(w);
+
+ ioctl(dev->fd, EVIOCGABS(ABS_Y), &abs_features);
+ dev->mouse.min_h = abs_features.minimum;
+ dev->mouse.rel_h = (double)(abs_features.maximum - abs_features.minimum)/(double)(h);
+ }
+ else if(!(dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE))
+ return;
+
+ /* update the local values */
+ if(dev->mouse.x > w - 1)
+ dev->mouse.x = w -1;
+ if(dev->mouse.y > h - 1)
+ dev->mouse.y = h -1;
+ dev->mouse.w = w;
+ dev->mouse.h = h;
+}
+
+
+EAPI const char *
+ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev)
+{
+ if(!dev)
+ return NULL;
+ return dev->info.name;
+}
+EAPI Ecore_Fb_Input_Device_Cap
+ecore_fb_input_device_cap_get(Ecore_Fb_Input_Device *dev)
+{
+ if(!dev)
+ return ECORE_FB_INPUT_DEVICE_CAP_NONE;
+ return dev->info.cap;
+}
+EAPI void
+ecore_fb_input_device_threshold_click_set(Ecore_Fb_Input_Device *dev, double threshold)
+{
+ if(!dev) return;
+ if(threshold == dev->mouse.threshold || threshold == 0) return;
+ dev->mouse.threshold = threshold;
+}
+EAPI double
+ecore_fb_input_device_threshold_click_get(Ecore_Fb_Input_Device *dev)
+{
+ if(!dev) return 0;
+ return dev->mouse.threshold;
+}
--- /dev/null
+#ifndef _ECORE_FB_PRIVATE_H
+#define _ECORE_FB_PRIVATE_H
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/version.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <linux/fb.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
+ #define kernel_ulong_t unsigned long
+ #define BITS_PER_LONG 32
+ #include <linux/input.h>
+ #undef kernel_ulong_t
+ #undef BITS_PER_LONG
+#else
+ #include <linux/input.h>
+#endif
+
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* ecore_fb_li.c */
+struct _Ecore_Fb_Input_Device
+{
+ int fd;
+ Ecore_Fd_Handler *handler;
+ int listen;
+ struct {
+ Ecore_Fb_Input_Device_Cap cap;
+ char *name;
+ char *dev;
+ } info;
+ struct
+ {
+ /* common mouse */
+ int x,y;
+ int w,h;
+
+ double last;
+ double prev;
+ double threshold;
+ /* absolute axis */
+ int min_w, min_h;
+ double rel_w, rel_h;
+ int event;
+ } mouse;
+ struct
+ {
+ int shift;
+ int ctrl;
+ int alt;
+ int lock;
+ } keyboard;
+};
+
+/* ecore_fb_ts.c */
+EAPI int ecore_fb_ts_init(void);
+EAPI void ecore_fb_ts_shutdown(void);
+
+/* ecore_fb_vt.c */
+int ecore_fb_vt_init(void);
+void ecore_fb_vt_shutdown(void);
+
+/* hacks to stop people NEEDING #include <linux/h3600_ts.h> */
+#ifndef TS_SET_CAL
+#define TS_SET_CAL 0x4014660b
+#endif
+#ifndef TS_GET_CAL
+#define TS_GET_CAL 0x8014660a
+#endif
+
+#endif
--- /dev/null
+typedef struct _Ecore_Fb_Ps2_Event Ecore_Fb_Ps2_Event;
+struct _Ecore_Fb_Ps2_Event
+{
+ unsigned char button;
+ unsigned char x;
+ unsigned char y;
+ unsigned char z;
+};
+
+static int _ecore_fb_ps2_event_byte_count = 0;
+static Ecore_Fb_Ps2_Event _ecore_fb_ps2_event;
+static int _ecore_fb_ps2_fd = 0;
+static int _ecore_fb_ps2_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+
+int
+ecore_fb_ps2_init(void)
+{
+ _ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR);
+ if (_ecore_fb_ps2_fd >= 0)
+ {
+ prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL);
+ fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ps2_fd_handler, NULL, NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ps2_fd);
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+void
+ecore_fb_ps2_shutdown(void)
+{
+ if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd);
+ _ecore_fb_ps2_fd = 0;
+}
+
+static int
+_ecore_fb_ps2_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ static int prev_x = 0, prev_y = 0, prev_button = 0;
+ static double last_time = 0;
+ static double last_last_time = 0;
+ int v = 0;
+
+ do
+ {
+ int x, y, button, i;
+ int num;
+ char *ptr;
+ double t;
+ int did_triple = 0;
+
+ ptr = (char *)&(_ecore_fb_ps2_event);
+ ptr += _ecore_fb_ps2_event_byte_count;
+ num = sizeof(Ecore_Fb_Ps2_Event) - _ecore_fb_ps2_event_byte_count;
+ v = read(_ecore_fb_ps2_fd, ptr, num);
+ if (v < 0) return 1;
+ _ecore_fb_ps2_event_byte_count += v;
+ if (v < num) return 1;
+ t = ecore_time_get();
+ _ecore_fb_ps2_event_byte_count = 0;
+ if (_ecore_fb_ps2_event.button & 0x10)
+ x = prev_x + (0xffffff00 | _ecore_fb_ps2_event.x);
+ else
+ x = prev_x + _ecore_fb_ps2_event.x;
+ if (_ecore_fb_ps2_event.button & 0x20)
+ y = prev_y - (0xffffff00 | _ecore_fb_ps2_event.y);
+ else
+ y = prev_y - _ecore_fb_ps2_event.y;
+ button = _ecore_fb_ps2_event.button & 0x7;
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x >= _ecore_fb_console_w) x = _ecore_fb_console_w - 1;
+ if (y >= _ecore_fb_console_h) y = _ecore_fb_console_h - 1;
+ /* add event to queue */
+ /* always add a move event */
+ if (1)
+ {
+ /* MOVE: mouse is down and was */
+ Ecore_Fb_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ for (i = 1; i <= 3; i++)
+ {
+ int mask;
+
+ mask = 1 << (i - 1);
+ if (((button & mask)) && (!(prev_button & mask)))
+ {
+ /* DOWN: mouse is down, but was not now */
+ Ecore_Fb_Event_Mouse_Button_Down *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->button = 1;
+ if ((t - last_time) <= _ecore_fb_double_click_time)
+ e->double_click = 1;
+ if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
+ {
+ did_triple = 1;
+ e->triple_click = 1;
+ }
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+ else if ((!(button & mask)) && ((prev_button & mask)))
+ {
+ /* UP: mouse was down, but is not now */
+ Ecore_Fb_Event_Mouse_Button_Up *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->button = 1;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+ }
+ if (did_triple)
+ {
+ last_time = 0;
+ last_last_time = 0;
+ }
+ else
+ {
+ last_last_time = last_time;
+ last_time = t;
+ }
+ retry:
+ prev_x = x;
+ prev_y = y;
+ prev_button = button;
+ }
+ while (v > 0);
+ return 1;
+}
+/**
+ * @defgroup Ecore_FB_Click_Group Framebuffer Double Click Functions
+ *
+ * Functions that deal with the double click time of the framebuffer.
+ */
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ * @ingroup Ecore_FB_Click_Group
+ */
+EAPI void
+ecore_fb_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_fb_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_x_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ * @ingroup Ecore_FB_Click_Group
+ */
+EAPI double
+ecore_fb_double_click_time_get(void)
+{
+ return _ecore_fb_double_click_time;
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_TSLIB
+# include <tslib.h>
+# include <errno.h>
+#endif
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+typedef struct _Ecore_Fb_Ts_Event Ecore_Fb_Ts_Event;
+typedef struct _Ecore_Fb_Ts_Calibrate Ecore_Fb_Ts_Calibrate;
+typedef struct _Ecore_Fb_Ts_Backlight Ecore_Fb_Ts_Backlight;
+typedef struct _Ecore_Fb_Ts_Contrast Ecore_Fb_Ts_Contrast;
+typedef struct _Ecore_Fb_Ts_Led Ecore_Fb_Ts_Led;
+typedef struct _Ecore_Fb_Ts_Flite Ecore_Fb_Ts_Flite;
+
+struct _Ecore_Fb_Ts_Event
+{
+ unsigned short pressure;
+ unsigned short x;
+ unsigned short y;
+ unsigned short _unused;
+};
+
+struct _Ecore_Fb_Ts_Calibrate
+{
+ int xscale;
+ int xtrans;
+ int yscale;
+ int ytrans;
+ int xyswap;
+};
+
+struct _Ecore_Fb_Ts_Backlight
+{
+ int on;
+ unsigned char brightness;
+};
+
+struct _Ecore_Fb_Ts_Contrast
+{
+ unsigned char contrast;
+};
+
+struct _Ecore_Fb_Ts_Led
+{
+ unsigned char on;
+ unsigned char blink_time;
+ unsigned char on_time;
+ unsigned char off_time;
+};
+
+struct _Ecore_Fb_Ts_Flite
+{
+ unsigned char mode;
+ unsigned char pwr;
+ unsigned char brightness;
+};
+
+static int _ecore_fb_ts_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_fb_ts_fd = -1;
+static int _ecore_fb_ts_event_byte_count = 0;
+static int _ecore_fb_ts_apply_cal = 0;
+static Ecore_Fb_Ts_Event _ecore_fb_ts_event;
+static Ecore_Fb_Ts_Calibrate _ecore_fb_ts_cal = {1,1,0,0,0};
+static Ecore_Fd_Handler *_ecore_fb_ts_fd_handler_handle = NULL;
+
+#ifdef HAVE_TSLIB
+struct tsdev *_ecore_fb_tslib_tsdev = NULL;
+struct ts_sample _ecore_fb_tslib_event;
+#endif
+
+static double _ecore_fb_double_click_time = 0.25;
+
+EAPI int
+ecore_fb_ts_init(void)
+{
+#ifdef HAVE_TSLIB
+ char *tslib_tsdevice = NULL;
+ if ( ( tslib_tsdevice = getenv("TSLIB_TSDEVICE") ) != NULL )
+ {
+ printf( "ECORE_FB: TSLIB_TSDEVICE = '%s'\n", tslib_tsdevice );
+ _ecore_fb_tslib_tsdev = ts_open( tslib_tsdevice, 1 ); /* 1 = nonblocking, 0 = blocking */
+
+ if ( !_ecore_fb_tslib_tsdev )
+ {
+ printf( "ECORE_FB: Can't ts_open (%s)\n", strerror( errno ) );
+ return 0;
+ }
+
+ if ( ts_config( _ecore_fb_tslib_tsdev ) )
+ {
+ printf( "ECORE_FB: Can't ts_config (%s)\n", strerror( errno ) );
+ return 0;
+ }
+ _ecore_fb_ts_fd = ts_fd( _ecore_fb_tslib_tsdev );
+ if ( _ecore_fb_ts_fd < 0 )
+ {
+ printf( "ECORE_FB: Can't open touchscreen (%s)\n", strerror( errno ) );
+ return 0;
+ }
+ }
+#else
+ _ecore_fb_ts_fd = open("/dev/touchscreen/0", O_RDONLY);
+#endif
+ if (_ecore_fb_ts_fd >= 0)
+ {
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ts_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ts_fd_handler, NULL,
+ NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ts_fd);
+ return 0;
+ }
+ // FIXME _ecore_fb_kbd_fd = open("/dev/touchscreen/key", O_RDONLY);
+ return 1;
+ }
+ return 0;
+}
+
+EAPI void
+ecore_fb_ts_shutdown(void)
+{
+ if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd);
+ if (_ecore_fb_ts_fd_handler_handle)
+ ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle);
+ _ecore_fb_ts_fd = -1;
+ _ecore_fb_ts_fd_handler_handle = NULL;
+}
+
+/**
+ * @defgroup Ecore_FB_Calibrate_Group Framebuffer Calibration Functions
+ *
+ * Functions that calibrate the screen.
+ */
+
+
+/**
+ * Calibrates the touschreen using the given parameters.
+ * @param xscale X scaling, where 256 = 1.0
+ * @param xtrans X translation.
+ * @param yscale Y scaling.
+ * @param ytrans Y translation.
+ * @param xyswap Swap X & Y flag.
+ * @ingroup Ecore_FB_Calibrate_Group
+ */
+EAPI void
+ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap)
+{
+ Ecore_Fb_Ts_Calibrate cal;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ cal.xscale = xscale;
+ cal.xtrans = xtrans;
+ cal.yscale = yscale;
+ cal.ytrans = ytrans;
+ cal.xyswap = xyswap;
+ if (ioctl(_ecore_fb_ts_fd, TS_SET_CAL, (void *)&cal))
+ {
+ _ecore_fb_ts_cal = cal;
+ _ecore_fb_ts_apply_cal = 1;
+
+ }
+}
+
+/**
+ * Retrieves the calibration parameters of the touchscreen.
+ * @param xscale Pointer to an integer in which to store the X scaling.
+ * Note that 256 = 1.0.
+ * @param xtrans Pointer to an integer in which to store the X translation.
+ * @param yscale Pointer to an integer in which to store the Y scaling.
+ * @param ytrans Pointer to an integer in which to store the Y translation.
+ * @param xyswap Pointer to an integer in which to store the Swap X & Y flag.
+ * @ingroup Ecore_FB_Calibrate_Group
+ */
+EAPI void
+ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap)
+{
+ Ecore_Fb_Ts_Calibrate cal;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ if (!_ecore_fb_ts_apply_cal)
+ {
+ if (ioctl(_ecore_fb_ts_fd, TS_GET_CAL, (void *)&cal))
+ _ecore_fb_ts_cal = cal;
+
+ }
+ else
+ cal = _ecore_fb_ts_cal;
+ if (xscale) *xscale = cal.xscale;
+ if (xtrans) *xtrans = cal.xtrans;
+ if (yscale) *yscale = cal.yscale;
+ if (ytrans) *ytrans = cal.ytrans;
+ if (xyswap) *xyswap = cal.xyswap;
+}
+
+static int
+_ecore_fb_ts_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ static int prev_x = 0, prev_y = 0, prev_pressure = 0;
+ static double last_time = 0;
+ static double last_last_time = 0;
+ int v = 0;
+
+ do
+ {
+ int x, y, pressure;
+ int num;
+ char *ptr;
+ double t;
+ int did_triple = 0;
+
+#ifdef HAVE_TSLIB
+ if (_ecore_fb_ts_apply_cal)
+ num = ts_read_raw(_ecore_fb_tslib_tsdev, &_ecore_fb_tslib_event, 1);
+ else
+ num = ts_read(_ecore_fb_tslib_tsdev, &_ecore_fb_tslib_event, 1);
+ if (num != 1) return 1; /* no more samples at this time */
+ x = _ecore_fb_tslib_event.x;
+ y = _ecore_fb_tslib_event.y;
+ pressure = _ecore_fb_tslib_event.pressure;
+ v = 1; /* loop, there might be more samples */
+ t = ecore_time_get();
+#else
+ ptr = (char *)&(_ecore_fb_ts_event);
+ ptr += _ecore_fb_ts_event_byte_count;
+ num = sizeof(Ecore_Fb_Ts_Event) - _ecore_fb_ts_event_byte_count;
+ v = read(_ecore_fb_ts_fd, ptr, num);
+ if (v < 0) return 1;
+ _ecore_fb_ts_event_byte_count += v;
+ if (v < num) return 1;
+ _ecore_fb_ts_event_byte_count = 0;
+ if (_ecore_fb_ts_apply_cal)
+ {
+ x = ((_ecore_fb_ts_cal.xscale * _ecore_fb_ts_event.x) >> 8) + _ecore_fb_ts_cal.xtrans;
+ y = ((_ecore_fb_ts_cal.yscale * _ecore_fb_ts_event.y) >> 8) + _ecore_fb_ts_cal.ytrans;
+ }
+ else
+ {
+ x = _ecore_fb_ts_event.x;
+ y = _ecore_fb_ts_event.y;
+ }
+ pressure = _ecore_fb_ts_event.pressure;
+#endif
+ /* add event to queue */
+ /* always add a move event */
+ if ((pressure) || (prev_pressure))
+ {
+ /* MOVE: mouse is down and was */
+ Ecore_Fb_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ if ((pressure) && (!prev_pressure))
+ {
+ /* DOWN: mouse is down, but was not now */
+ Ecore_Fb_Event_Mouse_Button_Down *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->button = 1;
+ if ((t - last_time) <= _ecore_fb_double_click_time)
+ e->double_click = 1;
+ if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
+ {
+ did_triple = 1;
+ e->triple_click = 1;
+ }
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+ else if ((!pressure) && (prev_pressure))
+ {
+ /* UP: mouse was down, but is not now */
+ Ecore_Fb_Event_Mouse_Button_Up *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
+ if (!e) goto retry;
+ e->x = prev_x;
+ e->y = prev_y;
+ e->button = 1;
+ ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+ if (did_triple)
+ {
+ last_time = 0;
+ last_last_time = 0;
+ }
+ else
+ {
+ last_last_time = last_time;
+ last_time = t;
+ }
+ retry:
+ prev_x = x;
+ prev_y = y;
+ prev_pressure = pressure;
+ }
+ while (v > 0);
+ return 1;
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+static int _ecore_fb_vt_do_switch = 0;
+
+static int _ecore_fb_vt_tty0_fd = 0;
+static int _ecore_fb_vt_tty_fd = 0;
+static int _ecore_fb_vt_current_vt = 0;
+static int _ecore_fb_vt_prev_vt = 0;
+
+static struct termios _ecore_fb_tty_prev_tio_mode;
+static struct vt_mode _ecore_fb_vt_prev_mode;
+
+static int _ecore_fb_signal_usr_handler(void *data, int type, void *ev);
+static Ecore_Event_Handler *_ecore_fb_user_handler = NULL;
+static int _ecore_fb_tty_prev_mode = 0;
+static int _ecore_fb_tty_prev_kd_mode = 0;
+
+/* callbacks for an attach/release of a vt */
+static void (*_ecore_fb_func_fb_lost) (void *data) = NULL;
+static void *_ecore_fb_func_fb_lost_data = NULL;
+static void (*_ecore_fb_func_fb_gain) (void *data) = NULL;
+static void *_ecore_fb_func_fb_gain_data = NULL;
+
+/* FIXME what is the filter for? */
+static Ecore_Event_Filter *_ecore_fb_filter_handler = NULL;
+
+static void *_ecore_fb_event_filter_start(void *data);
+static int _ecore_fb_event_filter_filter(void *data, void *loop_data, int type, void *event);
+static void _ecore_fb_event_filter_end(void *data, void *loop_data);
+
+/* prototypes */
+static void _ecore_fb_vt_switch(int vt);
+
+static int
+_ecore_fb_signal_usr_handler(void *data __UNUSED__, int type __UNUSED__, void *ev)
+{
+
+ Ecore_Event_Signal_User *e;
+
+ e = (Ecore_Event_Signal_User *)ev;
+ if (e->number == 1)
+ {
+ /* release vt */
+ if (_ecore_fb_func_fb_lost) _ecore_fb_func_fb_lost(_ecore_fb_func_fb_lost_data);
+ /* TODO stop listening from the devices? let the callback do it? */
+ ioctl(_ecore_fb_vt_tty_fd, VT_RELDISP, 1);
+ }
+ else if (e->number == 2)
+ {
+ /* attach vt */
+ if (_ecore_fb_func_fb_gain) _ecore_fb_func_fb_gain(_ecore_fb_func_fb_gain_data);
+ /* TODO reattach all devices */
+ }
+ return 1;
+}
+
+static void
+_ecore_fb_vt_switch(int vt)
+{
+ vt++;
+ if (_ecore_fb_vt_tty_fd != 0)
+ {
+ if (vt != _ecore_fb_vt_current_vt)
+ {
+ tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
+ }
+ }
+ ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, vt);
+}
+
+static int
+_ecore_fb_vt_setup(void)
+{
+ char buf[64];
+ struct termios tio;
+ struct vt_mode new_vtmode;
+
+ if(_ecore_fb_vt_current_vt != _ecore_fb_vt_prev_vt)
+ {
+ snprintf(buf, sizeof(buf), "/dev/tty%i", _ecore_fb_vt_current_vt);
+ if((_ecore_fb_vt_tty_fd = open(buf, O_RDWR)) < 0)
+ {
+ printf("[ecore_fb:vt_setup] cant open tty %d\n", _ecore_fb_vt_current_vt);
+ return 0;
+ }
+ close(_ecore_fb_vt_tty0_fd);
+ _ecore_fb_vt_tty0_fd = 0;
+ /* FIXME detach the process from current tty ? */
+ }
+ else
+ _ecore_fb_vt_tty_fd = _ecore_fb_vt_tty0_fd;
+ /* for backup */
+ tcgetattr(_ecore_fb_vt_tty_fd, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDGETMODE, &_ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_vt_tty_fd, VT_GETMODE, &_ecore_fb_vt_prev_mode);
+
+ if(ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ perror("[ecore_fb:vt_setup] cant set the mode to KD_GRAPHICS");
+ close(_ecore_fb_vt_tty_fd);
+ return 0;
+ }
+ ioctl(_ecore_fb_vt_tty_fd, KDGKBMODE, &_ecore_fb_tty_prev_mode);
+
+ /* support of switching */
+ new_vtmode.mode = VT_PROCESS;
+ new_vtmode.waitv = 0;
+ new_vtmode.relsig = SIGUSR1;
+ new_vtmode.acqsig = SIGUSR2;
+ if(ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &new_vtmode) < 0)
+ {
+ perror("[ecore_fb:vt_setup] cant set the tty mode");
+ close(_ecore_fb_vt_tty_fd);
+ return 0;
+ }
+ /* register signal handlers when alloc/detach of vt */
+ _ecore_fb_user_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
+ _ecore_fb_signal_usr_handler,
+ NULL);
+ /* What does this does? */
+ _ecore_fb_filter_handler = ecore_event_filter_add(_ecore_fb_event_filter_start, _ecore_fb_event_filter_filter, _ecore_fb_event_filter_end, NULL);
+
+ usleep(40000);
+ if(ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, _ecore_fb_vt_current_vt) < 0)
+ {
+ perror("[ecore_fb:vt_setup] error on VT_ACTIVATE");
+ close(_ecore_fb_vt_tty_fd);
+ return 0;
+ }
+ if(ioctl(_ecore_fb_vt_tty_fd, VT_WAITACTIVE, _ecore_fb_vt_current_vt) < 0)
+ {
+ perror("[ecore_fb:vt_setup] error on VT_WAITACTIVE");
+ close(_ecore_fb_vt_tty_fd);
+ return 0;
+ }
+ /* FIXME assign the fb to the tty in case isnt setup */
+ return 1;
+}
+
+int
+ecore_fb_vt_init(void)
+{
+ struct vt_stat vtstat;
+
+ /* as root you can allocate another tty */
+ if(!geteuid())
+ _ecore_fb_vt_do_switch = 1;
+ if((_ecore_fb_vt_tty0_fd = open("/dev/tty0", O_RDONLY)) < 0)
+ {
+ printf("[ecore_fb:init] cant open /dev/tty0\n");
+ return 0;
+ }
+ /* query current vt state */
+ if((ioctl(_ecore_fb_vt_tty0_fd, VT_GETSTATE, &vtstat)) < 0)
+ {
+ printf("[ecore_fb:init] cant get current tty state\n");
+ return 0;
+ }
+ _ecore_fb_vt_prev_vt = vtstat.v_active;
+ /* switch to another tty */
+ if(_ecore_fb_vt_do_switch)
+ {
+ int vtno;
+
+ if ((ioctl(_ecore_fb_vt_tty0_fd, VT_OPENQRY, &vtno) < 0))
+ {
+ printf("[ecore_fb:init] cant query for a vt\n");
+ return 0;
+ }
+ _ecore_fb_vt_current_vt = vtno;
+ }
+ /* use current tty */
+ else
+ _ecore_fb_vt_current_vt = _ecore_fb_vt_prev_vt;
+ if(!_ecore_fb_vt_setup())
+ {
+ printf("[ecore_fb:init] cant setup the vt, restoring previous mode...\n");
+ /* TODO finish this */
+ if(_ecore_fb_vt_do_switch)
+ {
+ printf("[ecore_fb:init] switching back to vt %d\n", _ecore_fb_vt_prev_vt);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+void
+ecore_fb_vt_shutdown(void)
+{
+ /* restore the previous mode */
+ if(_ecore_fb_vt_tty_fd != 0)
+ {
+ tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
+ ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &_ecore_fb_vt_prev_mode);
+ /* go back to previous vt */
+ close(_ecore_fb_vt_tty_fd);
+ _ecore_fb_vt_tty_fd = 0;
+ }
+
+ if(_ecore_fb_user_handler)
+ ecore_event_handler_del(_ecore_fb_user_handler);
+ _ecore_fb_user_handler = NULL;
+
+ if(_ecore_fb_filter_handler)
+ ecore_event_filter_del(_ecore_fb_filter_handler);
+ _ecore_fb_filter_handler = NULL;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ * @todo Documentation: Find out what this does.
+ */
+EAPI void
+ecore_fb_callback_gain_set(void (*func) (void *data), void *data)
+{
+ _ecore_fb_func_fb_gain = func;
+ _ecore_fb_func_fb_gain_data = data;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ * @todo Documentation: Find out what this does.
+ */
+EAPI void
+ecore_fb_callback_lose_set(void (*func) (void *data), void *data)
+{
+ _ecore_fb_func_fb_lost = func;
+ _ecore_fb_func_fb_lost_data = data;
+}
+typedef struct _Ecore_Fb_Filter_Data Ecore_Fb_Filter_Data;
+
+struct _Ecore_Fb_Filter_Data
+{
+ int last_event_type;
+};
+
+static void *
+_ecore_fb_event_filter_start(void *data __UNUSED__)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data));
+ return filter_data;
+}
+
+static int
+_ecore_fb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (!filter_data) return 1;
+ if (type == ECORE_FB_EVENT_MOUSE_MOVE)
+ {
+ if ((filter_data->last_event_type) == ECORE_FB_EVENT_MOUSE_MOVE)
+ {
+ filter_data->last_event_type = type;
+ return 0;
+ }
+ }
+ filter_data->last_event_type = type;
+ return 1;
+}
+
+static void
+_ecore_fb_event_filter_end(void *data __UNUSED__, void *loop_data)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (filter_data) free(filter_data);
+}
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_file.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef ECORE_FILE_H
+#define ECORE_FILE_H
+
+/*
+ * TODO:
+ * - More events, move/rename of directory file
+ */
+
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_FILE_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_FILE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+/**
+ * @file Ecore_File.h
+ * @brief Files utility functions
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct _Ecore_File_Monitor Ecore_File_Monitor;
+ typedef struct _Ecore_File_Monitor_Event Ecore_File_Monitor_Event;
+ typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job;
+
+ typedef enum
+ {
+ ECORE_FILE_EVENT_NONE,
+ ECORE_FILE_EVENT_CREATED_FILE,
+ ECORE_FILE_EVENT_CREATED_DIRECTORY,
+ ECORE_FILE_EVENT_DELETED_FILE,
+ ECORE_FILE_EVENT_DELETED_DIRECTORY,
+ ECORE_FILE_EVENT_DELETED_SELF,
+ ECORE_FILE_EVENT_MODIFIED
+ } Ecore_File_Event;
+
+
+ EAPI int ecore_file_init (void);
+ EAPI int ecore_file_shutdown (void);
+ EAPI long long ecore_file_mod_time (const char *file);
+ EAPI long long ecore_file_size (const char *file);
+ EAPI int ecore_file_exists (const char *file);
+ EAPI int ecore_file_is_dir (const char *file);
+ EAPI int ecore_file_mkdir (const char *dir);
+ EAPI int ecore_file_mkdirs (const char **dirs);
+ EAPI int ecore_file_mksubdirs (const char *base, const char **subdirs);
+ EAPI int ecore_file_rmdir (const char *dir);
+ EAPI int ecore_file_recursive_rm (const char *dir);
+ EAPI int ecore_file_mkpath (const char *path);
+ EAPI int ecore_file_mkpaths (const char **paths);
+ EAPI int ecore_file_cp (const char *src, const char *dst);
+ EAPI int ecore_file_mv (const char *src, const char *dst);
+ EAPI int ecore_file_symlink (const char *src, const char *dest);
+ EAPI char *ecore_file_realpath (const char *file);
+ EAPI int ecore_file_unlink (const char *file);
+ EAPI int ecore_file_remove (const char *file);
+ EAPI const char *ecore_file_file_get (const char *path);
+ EAPI char *ecore_file_dir_get (const char *path);
+
+ EAPI int ecore_file_can_read (const char *file);
+ EAPI int ecore_file_can_write (const char *file);
+ EAPI int ecore_file_can_exec (const char *file);
+ EAPI char *ecore_file_readlink (const char *link);
+ EAPI Eina_List *ecore_file_ls (const char *dir);
+ EAPI char *ecore_file_app_exe_get (const char *app);
+ EAPI char *ecore_file_escape_name (const char *filename);
+ EAPI char *ecore_file_strip_ext (const char *file);
+ EAPI int ecore_file_dir_is_empty (const char *dir);
+
+ EAPI Ecore_File_Monitor * ecore_file_monitor_add(const char *path,
+ void (*func) (void *data, Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+ EAPI void ecore_file_monitor_del(Ecore_File_Monitor *ecore_file_monitor);
+ EAPI const char *ecore_file_monitor_path_get(Ecore_File_Monitor *ecore_file_monitor);
+
+ EAPI int ecore_file_path_dir_exists(const char *in_dir);
+ EAPI int ecore_file_app_installed(const char *exe);
+ EAPI Eina_List *ecore_file_app_list(void);
+
+ EAPI int ecore_file_download(const char *url, const char *dst,
+ void (*completion_cb)(void *data,
+ const char *file,
+ int status),
+ int (*progress_cb)(void *data,
+ const char *file,
+ long int dltotal,
+ long int dlnow,
+ long int ultotal,
+ long int ulnow),
+ void *data,
+ Ecore_File_Download_Job **job_ret);
+ EAPI void ecore_file_download_abort_all(void);
+ EAPI void ecore_file_download_abort(Ecore_File_Download_Job *job);
+ EAPI int ecore_file_download_protocol_available(const char *protocol);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
+-I$(top_builddir)/src/lib/ecore \
+@EFL_ECORE_FILE_BUILD@ \
+@CURL_CFLAGS@ \
+@EVIL_CFLAGS@ \
+@EINA_CFLAGS@ \
+@WIN32_CPPFLAGS@
+
+AM_CFLAGS = @WIN32_CFLAGS@
+
+if BUILD_ECORE_CON
+lib_ecore_con_la = $(top_builddir)/src/lib/ecore_con/libecore_con.la
+endif
+
+if BUILD_ECORE_FILE
+
+lib_LTLIBRARIES = libecore_file.la
+include_HEADERS = Ecore_File.h
+
+libecore_file_la_SOURCES = \
+ecore_file.c \
+ecore_file_monitor.c \
+ecore_file_monitor_inotify.c \
+ecore_file_monitor_win32.c \
+ecore_file_monitor_poll.c \
+ecore_file_path.c \
+ecore_file_download.c
+
+libecore_file_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(lib_ecore_con_la) \
+@EVIL_LIBS@ \
+@EINA_LIBS@
+
+libecore_file_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_file_release_info@
+
+endif
+
+EXTRA_DIST = ecore_file_private.h
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#ifndef _MSC_VER
+# include <unistd.h>
+# include <libgen.h>
+#endif
+
+#ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+#endif
+
+#ifdef HAVE_FEATURES_H
+# include <features.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+
+#include "ecore_file_private.h"
+
+int _ecore_file_log_dom = -1;
+static int _ecore_file_init_count = 0;
+
+/* externally accessible functions */
+/**
+ * Initialize Ecore_File and the services it will use. Call this function
+ * once before you use any of the ecore file functions.
+ * @return Return the number howoften ecore_file_init() was call succesfully;
+ * 0 if it failed.
+ */
+EAPI int
+ecore_file_init()
+{
+ if (++_ecore_file_init_count != 1)
+ return _ecore_file_init_count;
+ _ecore_file_log_dom = eina_log_domain_register("EcoreFile", ECORE_FILE_DEFAULT_LOG_COLOR);
+ if(_ecore_file_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the ecore file module.");
+ return --_ecore_file_init_count;
+ }
+ ecore_file_path_init();
+ ecore_file_monitor_init();
+ ecore_file_download_init();
+
+ /* FIXME: were the tests disabled for a good reason ? */
+
+ /*
+ if (!ecore_file_monitor_init())
+ goto shutdown_ecore_file_path;
+
+ if (!ecore_file_download_init())
+ goto shutdown_ecore_file_monitor;
+ */
+
+ return _ecore_file_init_count;
+
+ /*
+ shutdown_ecore_file_monitor:
+ ecore_file_monitor_shutdown();
+ shutdown_ecore_file_path:
+ ecore_file_path_shutdown();
+
+ return --_ecore_file_init_count;
+ */
+}
+
+/**
+ * Shutdown the Ecore_File
+ * @return returns the number of libraries that still uses Ecore_File
+ */
+EAPI int
+ecore_file_shutdown()
+{
+ if (--_ecore_file_init_count != 0)
+ return _ecore_file_init_count;
+
+ ecore_file_download_shutdown();
+ ecore_file_monitor_shutdown();
+ ecore_file_path_shutdown();
+ eina_log_domain_unregister(_ecore_file_log_dom);
+ _ecore_file_log_dom = -1;
+ return _ecore_file_init_count;
+}
+
+/**
+ * Get the time of the last modification to the give file
+ * @param file The name of the file
+ * @return Return the time of the last data modification, if an error should
+ * occur it will return 0
+ */
+EAPI long long
+ecore_file_mod_time(const char *file)
+{
+ struct stat st;
+
+ if (stat(file, &st) < 0) return 0;
+ return st.st_mtime;
+}
+
+/**
+ * Get the size of the given file
+ * @param file The name of the file
+ * @return The size of the file in byte
+ */
+EAPI long long
+ecore_file_size(const char *file)
+{
+ struct stat st;
+
+ if (stat(file, &st) < 0) return 0;
+ return st.st_size;
+}
+
+/**
+ * Check if file exists
+ * @param file The name of the file
+ * @return 1 if file exists on local filesystem, 0 otherwise
+ */
+EAPI int
+ecore_file_exists(const char *file)
+{
+ struct stat st;
+
+ /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/
+ if (stat(file, &st) < 0 && strcmp(file, "/")) return 0;
+ return 1;
+}
+
+/**
+ * Check if file is a directory
+ * @param file The name of the file
+ * @return 1 if file exist and is a directory, 0 otherwise
+ */
+EAPI int
+ecore_file_is_dir(const char *file)
+{
+ struct stat st;
+
+ if (stat(file, &st) < 0) return 0;
+ if (S_ISDIR(st.st_mode)) return 1;
+ return 0;
+}
+
+static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+
+/**
+ * Create a new directory
+ * @param dir The name of the directory to create
+ * @return 1 on successfull creation, 0 on failure
+ *
+ * The directory is created with the mode: S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
+ */
+EAPI int
+ecore_file_mkdir(const char *dir)
+{
+ if (mkdir(dir, default_mode) < 0) return 0;
+ return 1;
+}
+
+/**
+ * Create complete directory in a batch.
+ *
+ * @param dirs list of directories, null terminated.
+ * @return number of successfull directories created, -1 if dirs is NULL.
+ *
+ * @see ecore_file_mkdir() and ecore_file_mkpaths()
+ */
+EAPI int
+ecore_file_mkdirs(const char **dirs)
+{
+ int i = 0;
+
+ if (!dirs) return -1;
+
+ for (; *dirs != NULL; dirs++)
+ if (ecore_file_mkdir(*dirs))
+ i++;
+ return i;
+}
+
+/**
+ * Create complete list of sub-directories in a batch (optimized).
+ *
+ * @param base the base directory to act on, will be created if does
+ * not exists.
+ * @param subdirs list of directories, null terminated. These are
+ * created similarly to ecore_file_mkdir(), so same mode and whole
+ * path to that point must exists. So if creating base/a/b/c,
+ * provide subdirs with "a", "a/b" and "a/b/c" in that order!
+ *
+ * @return number of successfull directories created, -1 if subdirs or
+ * base is NULL or invalid.
+ *
+ * @see ecore_file_mkdir() and ecore_file_mkpaths()
+ */
+EAPI int
+ecore_file_mksubdirs(const char *base, const char **subdirs)
+{
+#ifndef HAVE_ATFILE_SOURCE
+ char buf[PATH_MAX];
+ int baselen;
+#else
+ int fd;
+ DIR *dir;
+#endif
+ int i;
+
+ if (!subdirs) return -1;
+ if ((!base) || (base[0] == '\0')) return -1;
+
+ if ((!ecore_file_is_dir(base)) && (!ecore_file_mkpath(base)))
+ return 0;
+
+#ifndef HAVE_ATFILE_SOURCE
+ baselen = eina_strlcpy(buf, base, sizeof(buf));
+ if ((baselen < 1) || (baselen + 1 >= (int)sizeof(buf)))
+ return 0;
+
+ if (buf[baselen - 1] != '/')
+ {
+ buf[baselen] = '/';
+ baselen++;
+ }
+#else
+ dir = opendir(base);
+ if (!dir)
+ return 0;
+ fd = dirfd(dir);
+#endif
+
+ i = 0;
+ for (; *subdirs != NULL; subdirs++)
+ {
+ struct stat st;
+
+#ifndef HAVE_ATFILE_SOURCE
+ eina_strlcpy(buf + baselen, *subdirs, sizeof(buf) - baselen);
+ if (stat(buf, &st) == 0)
+#else
+ if (fstatat(fd, *subdirs, &st, 0) == 0)
+#endif
+ {
+ if (S_ISDIR(st.st_mode))
+ {
+ i++;
+ continue;
+ }
+ }
+ else
+ {
+ if (errno == ENOENT)
+ {
+#ifndef HAVE_ATFILE_SOURCE
+ if (mkdir(buf, default_mode) == 0)
+#else
+ if (mkdirat(fd, *subdirs, default_mode) == 0)
+#endif
+ {
+ i++;
+ continue;
+ }
+ }
+ }
+ }
+
+#ifdef HAVE_ATFILE_SOURCE
+ closedir(dir);
+#endif
+
+ return i;
+}
+
+/**
+ * Delete the given dir
+ * @param dir The name of the directory to delete
+ * @return 1 on success, 0 on failure
+ */
+EAPI int
+ecore_file_rmdir(const char *dir)
+{
+ if (rmdir(dir) < 0) return 0;
+ return 1;
+}
+
+/**
+ * Delete the given file
+ * @param file The name of the file to delete
+ * @return 1 on success, 0 on failure
+ */
+EAPI int
+ecore_file_unlink(const char *file)
+{
+ if (unlink(file) < 0) return 0;
+ return 1;
+}
+
+/**
+ * Remove the given file or directory
+ * @param file The name of the file or directory to delete
+ * @return 1 on success, 0 on failure
+ */
+EAPI int
+ecore_file_remove(const char *file)
+{
+ if (remove(file) < 0) return 0;
+ return 1;
+}
+
+/**
+ * Delete a directory and all its contents
+ * @param dir The name of the directory to delete
+ * @return 1 on success, 0 on failure
+ *
+ * If dir is a link only the link is removed
+ */
+EAPI int
+ecore_file_recursive_rm(const char *dir)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ char path[PATH_MAX], buf[PATH_MAX];
+ struct stat st;
+ int ret;
+
+ if (readlink(dir, buf, sizeof(buf)) > 0)
+ return ecore_file_unlink(dir);
+
+ ret = stat(dir, &st);
+ if ((ret == 0) && (S_ISDIR(st.st_mode)))
+ {
+ ret = 1;
+ if (stat(dir, &st) == -1) return 0;
+ dirp = opendir(dir);
+ if (dirp)
+ {
+ while ((dp = readdir(dirp)))
+ {
+ if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
+ {
+ snprintf(path, PATH_MAX, "%s/%s", dir, dp->d_name);
+ if (!ecore_file_recursive_rm(path))
+ ret = 0;
+ }
+ }
+ closedir(dirp);
+ }
+ if (!ecore_file_rmdir(dir)) ret = 0;
+ return ret;
+ }
+ else
+ {
+ if (ret == -1) return 0;
+ return ecore_file_unlink(dir);
+ }
+}
+
+static inline int
+_ecore_file_mkpath_if_not_exists(const char *path)
+{
+ struct stat st;
+
+ if (stat(path, &st) < 0)
+ return ecore_file_mkdir(path);
+ else if (!S_ISDIR(st.st_mode))
+ return 0;
+ else
+ return 1;
+}
+
+/**
+ * Create a complete path
+ * @param path The path to create
+ * @return 1 on success, 0 on failure
+ *
+ * @see ecore_file_mkpaths() and ecore_file_mkdir()
+ */
+EAPI int
+ecore_file_mkpath(const char *path)
+{
+ char ss[PATH_MAX];
+ unsigned int i;
+
+ if (ecore_file_is_dir(path))
+ return 1;
+
+ for (i = 0; path[i] != '\0'; ss[i] = path[i], i++)
+ {
+ if (i == sizeof(ss) - 1) return 0;
+ if ((path[i] == '/') && (i > 0))
+ {
+ ss[i] = '\0';
+ if (!_ecore_file_mkpath_if_not_exists(ss))
+ return 0;
+ }
+ }
+ ss[i] = '\0';
+ return _ecore_file_mkpath_if_not_exists(ss);
+}
+
+/**
+ * Create complete paths in a batch.
+ *
+ * @param paths list of paths, null terminated.
+ * @return number of successfull paths created, -1 if paths is NULL.
+ *
+ * @see ecore_file_mkpath() and ecore_file_mkdirs()
+ */
+EAPI int
+ecore_file_mkpaths(const char **paths)
+{
+ int i = 0;
+
+ if (!paths) return -1;
+
+ for (; *paths != NULL; paths++)
+ if (ecore_file_mkpath(*paths))
+ i++;
+ return i;
+}
+
+/**
+ * Copy a file
+ * @param src The name of the source file
+ * @param dst The name of the destination file
+ * @return 1 on success, 0 on failure
+ */
+EAPI int
+ecore_file_cp(const char *src, const char *dst)
+{
+ FILE *f1, *f2;
+ char buf[16384];
+ char realpath1[PATH_MAX], realpath2[PATH_MAX];
+ size_t num;
+ int ret = 1;
+
+ if (!realpath(src, realpath1)) return 0;
+ if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return 0;
+
+ f1 = fopen(src, "rb");
+ if (!f1) return 0;
+ f2 = fopen(dst, "wb");
+ if (!f2)
+ {
+ fclose(f1);
+ return 0;
+ }
+ while ((num = fread(buf, 1, sizeof(buf), f1)) > 0)
+ {
+ if (fwrite(buf, 1, num, f2) != num) ret = 0;
+ }
+ fclose(f1);
+ fclose(f2);
+ return ret;
+}
+
+/**
+ * Move a file
+ * @param src The name of the source file
+ * @param dst The name of the destination file
+ * @return 1 on success, 0 on failure
+ */
+EAPI int
+ecore_file_mv(const char *src, const char *dst)
+{
+ char buf[PATH_MAX];
+ int fd;
+
+ if (rename(src, dst))
+ {
+ // File cannot be moved directly because
+ // it resides on a different mount point.
+ if (errno == EXDEV)
+ {
+ struct stat st;
+
+ // Make sure this is a regular file before
+ // we do anything fancy.
+ stat(src, &st);
+ if (S_ISREG(st.st_mode))
+ {
+ char *dir;
+
+ dir = ecore_file_dir_get(dst);
+ // Since we can't directly rename, try to
+ // copy to temp file in the dst directory
+ // and then rename.
+ snprintf(buf, sizeof(buf), "%s/.%s.tmp.XXXXXX",
+ dir, ecore_file_file_get(dst));
+ free(dir);
+ fd = mkstemp(buf);
+ if (fd < 0)
+ {
+ perror("mkstemp");
+ goto FAIL;
+ }
+ close(fd);
+
+ // Copy to temp file
+ if (!ecore_file_cp(src, buf))
+ goto FAIL;
+
+ // Set file permissions of temp file to match src
+ chmod(buf, st.st_mode);
+
+ // Try to atomically move temp file to dst
+ if (rename(buf, dst))
+ {
+ // If we still cannot atomically move
+ // do a normal copy and hope for the best.
+ if (!ecore_file_cp(buf, dst))
+ goto FAIL;
+ }
+
+ // Delete temporary file and src
+ ecore_file_unlink(buf);
+ ecore_file_unlink(src);
+ goto PASS;
+ }
+ }
+ goto FAIL;
+ }
+
+PASS:
+ return 1;
+
+FAIL:
+ return 0;
+}
+
+/**
+ * Create a symbolic link
+ * @param src The name of the file to link
+ * @param dest The name of link
+ * @return 1 on success, 0 on failure
+ */
+EAPI int
+ecore_file_symlink(const char *src, const char *dest)
+{
+ if (!symlink(src, dest)) return 1;
+
+ return 0;
+}
+
+/**
+ * Get the canonicalized absolute pathname
+ * @param file The file path
+ * @return The canonicalized absolute pathname; on failure it will return
+ * an empty string
+ */
+EAPI char *
+ecore_file_realpath(const char *file)
+{
+ char buf[PATH_MAX];
+
+ /*
+ * Some implementations of realpath do not conform to the SUS.
+ * And as a result we must prevent a null arg from being passed.
+ */
+ if (!file) return strdup("");
+ if (!realpath(file, buf)) return strdup("");
+
+ return strdup(buf);
+}
+
+/**
+ * Get the filename from a give path
+ * @param path The complete path
+ * @return Only the file name
+ */
+EAPI const char *
+ecore_file_file_get(const char *path)
+{
+ char *result = NULL;
+
+ if (!path) return NULL;
+ if ((result = strrchr(path, '/'))) result++;
+ else result = (char *)path;
+ return result;
+}
+
+/**
+ * Get the directory where file reside
+ * @param file The name of the file
+ * @return The directory name
+ */
+EAPI char *
+ecore_file_dir_get(const char *file)
+{
+ char *p;
+ char buf[PATH_MAX];
+
+ if (!file) return NULL;
+ strncpy(buf, file, PATH_MAX);
+ buf[PATH_MAX - 1] = 0;
+ p = dirname(buf);
+ return strdup(p);
+}
+
+/**
+ * Check if file can be read
+ * @param file The name of the file
+ * @return 1 if the file is readable, 0 otherwise
+ */
+EAPI int
+ecore_file_can_read(const char *file)
+{
+ if (!file) return 0;
+ if (!access(file, R_OK)) return 1;
+ return 0;
+}
+
+/**
+ * Check if file can be written
+ * @param file The name of the file
+ * @return 1 if the file is writable, 0 otherwise
+ */
+EAPI int
+ecore_file_can_write(const char *file)
+{
+ if (!file) return 0;
+ if (!access(file, W_OK)) return 1;
+ return 0;
+}
+
+/**
+ * Check if file can be executed
+ * @param file The name of the file
+ * @return 1 if the file can be executed, 0 otherwise
+ */
+EAPI int
+ecore_file_can_exec(const char *file)
+{
+ if (!file) return 0;
+ if (!access(file, X_OK)) return 1;
+ return 0;
+}
+
+/**
+ * Get the path pointed by link
+ * @param link The name of the link
+ * @return The path pointed by link or NULL
+ */
+EAPI char *
+ecore_file_readlink(const char *link)
+{
+ char buf[PATH_MAX];
+ int count;
+
+ if ((count = readlink(link, buf, sizeof(buf))) < 0) return NULL;
+ buf[count] = 0;
+ return strdup(buf);
+}
+
+/**
+ * Get the list of the files and directories in a given directory. The list
+ * will be sorted with strcoll as compare function. That means that you may
+ * want to set the current locale for the category LC_COLLATE with setlocale().
+ * For more information see the manual pages of strcoll and setlocale.
+ * The list will not contain the directory entries for '.' and '..'.
+ * @param dir The name of the directory to list
+ * @return Return an Eina_List containing all the files in the directory;
+ * on failure it returns NULL.
+ */
+EAPI Eina_List *
+ecore_file_ls(const char *dir)
+{
+ char *f;
+ DIR *dirp;
+ struct dirent *dp;
+ Eina_List *list = NULL;
+
+ dirp = opendir(dir);
+ if (!dirp) return NULL;
+
+ while ((dp = readdir(dirp)))
+ {
+ if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
+ {
+ f = strdup(dp->d_name);
+ list = eina_list_append(list, f);
+ }
+ }
+ closedir(dirp);
+
+ list = eina_list_sort(list, eina_list_count(list), EINA_COMPARE_CB(strcoll));
+
+ return list;
+}
+
+/**
+ * FIXME: To be documented.
+ */
+EAPI char *
+ecore_file_app_exe_get(const char *app)
+{
+ char *p, *pp, *exe1 = NULL, *exe2 = NULL;
+ char *exe = NULL;
+ int in_quot_dbl = 0, in_quot_sing = 0, restart = 0;
+
+ if (!app) return NULL;
+
+ p = (char *)app;
+restart:
+ while ((*p) && (isspace(*p))) p++;
+ exe1 = p;
+ while (*p)
+ {
+ if (in_quot_sing)
+ {
+ if (*p == '\'')
+ in_quot_sing = 0;
+ }
+ else if (in_quot_dbl)
+ {
+ if (*p == '\"')
+ in_quot_dbl = 0;
+ }
+ else
+ {
+ if (*p == '\'')
+ in_quot_sing = 1;
+ else if (*p == '\"')
+ in_quot_dbl = 1;
+ if ((isspace(*p)) && (!((p > app) && (p[-1] != '\\'))))
+ break;
+ }
+ p++;
+ }
+ exe2 = p;
+ if (exe2 == exe1) return NULL;
+ if (*exe1 == '~')
+ {
+ char *homedir;
+ int len;
+
+ /* Skip ~ */
+ exe1++;
+
+ homedir = getenv("HOME");
+ if (!homedir) return NULL;
+ len = strlen(homedir);
+ if (exe) free(exe);
+ exe = malloc(len + exe2 - exe1 + 2);
+ if (!exe) return NULL;
+ pp = exe;
+ if (len)
+ {
+ strcpy(exe, homedir);
+ pp += len;
+ if (*(pp - 1) != '/')
+ {
+ *pp = '/';
+ pp++;
+ }
+ }
+ }
+ else
+ {
+ if (exe) free(exe);
+ exe = malloc(exe2 - exe1 + 1);
+ if (!exe) return NULL;
+ pp = exe;
+ }
+ p = exe1;
+ restart = 0;
+ in_quot_dbl = 0;
+ in_quot_sing = 0;
+ while (*p)
+ {
+ if (in_quot_sing)
+ {
+ if (*p == '\'')
+ in_quot_sing = 0;
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ else if (in_quot_dbl)
+ {
+ if (*p == '\"')
+ in_quot_dbl = 0;
+ else
+ {
+ /* techcincally this is wrong. double quotes also accept
+ * special chars:
+ *
+ * $, `, \
+ */
+ *pp = *p;
+ pp++;
+ }
+ }
+ else
+ {
+ /* technically we should handle special chars:
+ *
+ * $, `, \, etc.
+ */
+ if ((p > exe1) && (p[-1] == '\\'))
+ {
+ if (*p != '\n')
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ else if ((p > exe1) && (*p == '='))
+ {
+ restart = 1;
+ *pp = *p;
+ pp++;
+ }
+ else if (*p == '\'')
+ in_quot_sing = 1;
+ else if (*p == '\"')
+ in_quot_dbl = 1;
+ else if (isspace(*p))
+ {
+ if (restart)
+ goto restart;
+ else
+ break;
+ }
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ p++;
+ }
+ *pp = 0;
+ return exe;
+}
+
+/**
+ * Add the escape sequence ('\\') to the given filename
+ * @param filename The file name
+ * @return The file name with special characters escaped; if the length of the
+ * resulting string is longer than PATH_MAX it will return NULL
+ */
+EAPI char *
+ecore_file_escape_name(const char *filename)
+{
+ const char *p;
+ char *q;
+ char buf[PATH_MAX];
+
+ p = filename;
+ q = buf;
+ while (*p)
+ {
+ if ((q - buf) > (PATH_MAX - 6)) return NULL;
+ if (
+ (*p == ' ') || (*p == '\t') || (*p == '\n') ||
+ (*p == '\\') || (*p == '\'') || (*p == '\"') ||
+ (*p == ';') || (*p == '!') || (*p == '#') ||
+ (*p == '$') || (*p == '%') || (*p == '&') ||
+ (*p == '*') || (*p == '(') || (*p == ')') ||
+ (*p == '[') || (*p == ']') || (*p == '{') ||
+ (*p == '}') || (*p == '|') || (*p == '<') ||
+ (*p == '>') || (*p == '?')
+ )
+ {
+ *q = '\\';
+ q++;
+ }
+ *q = *p;
+ q++;
+ p++;
+ }
+ *q = 0;
+ return strdup(buf);
+}
+
+/**
+ * Remove the extension from a given path
+ * @param path The name of the file
+ * @return A newly allocated string with the extension stripped out or NULL on errors
+ */
+EAPI char *
+ecore_file_strip_ext(const char *path)
+{
+ char *p, *file = NULL;
+
+ p = strrchr(path, '.');
+ if (!p)
+ file = strdup(path);
+ else if (p != path)
+ {
+ file = malloc(((p - path) + 1) * sizeof(char));
+ if (file)
+ {
+ memcpy(file, path, (p - path));
+ file[p - path] = 0;
+ }
+ }
+
+ return file;
+}
+
+/**
+ * Check if the given directory is empty. The '.' and '..' files will be ignored.
+ * @param dir The name of the directory to check
+ * @return 1 if directory is empty, 0 if it has at least one file or -1 in case of errors
+ */
+EAPI int
+ecore_file_dir_is_empty(const char *dir)
+{
+ DIR *dirp;
+ struct dirent *dp;
+
+ dirp = opendir(dir);
+ if (!dirp) return -1;
+
+ while ((dp = readdir(dirp)))
+ {
+ if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
+ {
+ closedir(dirp);
+ return 0;
+ }
+ }
+
+ closedir(dirp);
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef BUILD_ECORE_CON
+# include "Ecore_Con.h"
+#endif
+
+#include "ecore_file_private.h"
+
+#ifdef BUILD_ECORE_CON
+
+#define ECORE_MAGIC_FILE_DOWNLOAD_JOB 0xf7427cb8
+
+struct _Ecore_File_Download_Job
+{
+ ECORE_MAGIC;
+
+ Ecore_Con_Url *url_con;
+ FILE *file;
+
+ char *dst;
+
+ void (*completion_cb)(void *data, const char *file, int status);
+
+ int (*progress_cb) (void *data, const char *file,
+ long int dltotal, long int dlnow,
+ long int ultotal, long int ulnow);
+};
+
+#ifdef HAVE_CURL
+Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst,
+ void (*completion_cb)(void *data, const char *file, int status),
+ int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow),
+ void *data);
+
+static int _ecore_file_download_url_complete_cb(void *data, int type, void *event);
+static int _ecore_file_download_url_progress_cb(void *data, int type, void *event);
+#endif
+
+static Ecore_Event_Handler *_url_complete_handler = NULL;
+static Ecore_Event_Handler *_url_progress_download = NULL;
+static Eina_List *_job_list;
+
+#endif /* BUILD_ECORE_CON */
+
+int
+ecore_file_download_init(void)
+{
+#ifdef BUILD_ECORE_CON
+ if (!ecore_con_url_init())
+ return 0;
+
+# ifdef HAVE_CURL
+ _url_complete_handler = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _ecore_file_download_url_complete_cb, NULL);
+ _url_progress_download = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _ecore_file_download_url_progress_cb, NULL);
+# endif
+
+#endif /* BUILD_ECORE_CON */
+
+ return 1;
+}
+
+void
+ecore_file_download_shutdown(void)
+{
+#ifdef BUILD_ECORE_CON
+ if (_url_complete_handler)
+ ecore_event_handler_del(_url_complete_handler);
+ if (_url_progress_download)
+ ecore_event_handler_del(_url_progress_download);
+ _url_complete_handler = NULL;
+ _url_progress_download = NULL;
+ ecore_file_download_abort_all();
+
+ ecore_con_url_shutdown();
+#endif /* BUILD_ECORE_CON */
+}
+
+EAPI void
+ecore_file_download_abort_all(void)
+{
+#ifdef BUILD_ECORE_CON
+ Ecore_File_Download_Job *job;
+
+ EINA_LIST_FREE(_job_list, job)
+ ecore_file_download_abort(job);
+#endif /* BUILD_ECORE_CON */
+}
+
+/**
+ * Download @p url to the given @p dst
+ * @param url The complete url to download
+ * @param dst The local file to save the downloaded to
+ * @param completion_cb A callback called on download complete
+ * @param progress_cb A callback called during the download operation
+ * @param data User data passed to both callbacks
+ * @param job_ret If the protocol in use is http or ftp, this parameter will be
+ * filled with the job. Then you can use ecore_file_download_abort() to cancel it.
+ *
+ * @return 1 if the download start or 0 on failure
+ *
+ * You must provide the full url, including 'http://', 'ftp://' or 'file://'.\n
+ * If @p dst already exist it will not be overwritten and the function will fail.\n
+ * Ecore must be compiled with CURL to download using http and ftp protocols.\n
+ * The @p status param in the @p completion_cb() will be 0 if the download goes well or
+ * 1 in case of failure.
+ */
+EAPI int
+ecore_file_download(const char *url, const char *dst,
+ void (*completion_cb)(void *data, const char *file, int status),
+ int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow),
+ void *data, Ecore_File_Download_Job **job_ret)
+{
+#ifdef BUILD_ECORE_CON
+ char *dir = ecore_file_dir_get(dst);
+
+ if (!ecore_file_is_dir(dir))
+ {
+ free(dir);
+ return 0;
+ }
+ free(dir);
+ if (ecore_file_exists(dst)) return 0;
+
+ /* FIXME: Add handlers for http and ftp! */
+ if (!strncmp(url, "file://", 7))
+ {
+ /* FIXME: Maybe fork? Might take a while to copy.
+ * Check filesize? */
+ /* Just copy it */
+
+ url += 7;
+ /* skip hostname */
+ url = strchr(url, '/');
+ return ecore_file_cp(url, dst);
+ }
+# ifdef HAVE_CURL
+ else if ((!strncmp(url, "http://", 7)) ||
+ (!strncmp(url, "ftp://", 6)))
+ {
+ /* download */
+ Ecore_File_Download_Job *job;
+
+ job = _ecore_file_download_curl(url, dst, completion_cb, progress_cb, data);
+ if(job_ret) *job_ret = job;
+ return job != NULL;
+ }
+# endif
+ else
+ {
+ return 0;
+ }
+#else
+ completion_cb = NULL;
+ progress_cb = NULL;
+ data = NULL;
+ return 0;
+#endif /* BUILD_ECORE_CON */
+}
+
+/**
+ * Check if the given protocol is available
+ * @param protocol The protocol to check
+ * @return 1 if protocol is handled or 0 if not
+ *
+ * @p protocol can be 'http://', 'ftp://' or 'file://'.\n
+ * Ecore must be compiled with CURL to handle http and ftp protocols.
+ */
+EAPI int
+ecore_file_download_protocol_available(const char *protocol)
+{
+#ifdef BUILD_ECORE_CON
+ if (!strncmp(protocol, "file://", 7)) return 1;
+# ifdef HAVE_CURL
+ else if (!strncmp(protocol, "http://", 7)) return 1;
+ else if (!strncmp(protocol, "ftp://", 6)) return 1;
+# endif
+#endif /* BUILD_ECORE_CON */
+
+ return 0;
+}
+
+#ifdef BUILD_ECORE_CON
+
+# ifdef HAVE_CURL
+static int
+_ecore_file_download_url_compare_job(const void *data1, const void *data2)
+{
+ const Ecore_File_Download_Job *job = data1;
+ const Ecore_Con_Url *url = data2;
+
+ if (job->url_con == url) return 0;
+ return -1;
+}
+
+static int
+_ecore_file_download_url_complete_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Con_Event_Url_Complete *ev = event;
+ Ecore_File_Download_Job *job;
+
+ job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
+ if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
+
+
+ if (job->completion_cb)
+ job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, !ev->status);
+
+ _job_list = eina_list_remove(_job_list, job);
+ fclose(job->file);
+ free(job->dst);
+ free(job);
+
+ return 0;
+}
+
+static int
+_ecore_file_download_url_progress_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+/* this reports the downloads progress. if we return 0, then download
+ * continues, if we return anything else, then the download stops */
+ Ecore_Con_Event_Url_Progress *ev = event;
+ Ecore_File_Download_Job *job;
+
+ job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
+ if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
+
+ if (job->progress_cb)
+ if (job->progress_cb(ecore_con_url_data_get(job->url_con), job->dst,
+ (long int) ev->down.total, (long int) ev->down.now,
+ (long int) ev->up.total, (long int) ev->up.now) != 0)
+ {
+ _job_list = eina_list_remove(_job_list, job);
+ fclose(job->file);
+ free(job->dst);
+ free(job);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+Ecore_File_Download_Job *
+_ecore_file_download_curl(const char *url, const char *dst,
+ void (*completion_cb)(void *data, const char *file,
+ int status),
+ int (*progress_cb)(void *data, const char *file,
+ long int dltotal, long int dlnow,
+ long int ultotal, long int ulnow),
+ void *data)
+{
+ Ecore_File_Download_Job *job;
+
+ job = calloc(1, sizeof(Ecore_File_Download_Job));
+ if (!job) return NULL;
+
+ ECORE_MAGIC_SET(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB);
+
+ job->file = fopen(dst, "wb");
+ if (!job->file)
+ {
+ free(job);
+ return NULL;
+ }
+ job->url_con = ecore_con_url_new(url);
+ if (!job->url_con)
+ {
+ fclose(job->file);
+ free(job);
+ return NULL;
+ }
+
+ ecore_con_url_fd_set(job->url_con, fileno(job->file));
+ ecore_con_url_data_set(job->url_con, data);
+
+ job->dst = strdup(dst);
+
+ job->completion_cb = completion_cb;
+ job->progress_cb = progress_cb;
+ _job_list = eina_list_append(_job_list, job);
+
+ ecore_con_url_send(job->url_con, NULL, 0, NULL);
+
+ return job;
+}
+# endif
+#endif
+
+/**
+ * Abort the given download job
+ * @param job The download job to abort
+ */
+
+EAPI void
+ecore_file_download_abort(Ecore_File_Download_Job *job)
+{
+#ifdef BUILD_ECORE_CON
+# ifdef HAVE_CURL
+ ecore_con_url_destroy(job->url_con);
+# endif
+ _job_list = eina_list_remove(_job_list, job);
+ fclose(job->file);
+ free(job->dst);
+ free(job);
+#endif /* BUILD_ECORE_CON */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_file_private.h"
+
+typedef enum {
+ ECORE_FILE_MONITOR_TYPE_NONE,
+#ifdef HAVE_INOTIFY
+ ECORE_FILE_MONITOR_TYPE_INOTIFY,
+#endif
+#ifdef HAVE_NOTIFY_WIN32
+ ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32,
+#endif
+#ifdef HAVE_POLL
+ ECORE_FILE_MONITOR_TYPE_POLL
+#endif
+} Ecore_File_Monitor_Type;
+
+static Ecore_File_Monitor_Type monitor_type = ECORE_FILE_MONITOR_TYPE_NONE;
+
+int
+ecore_file_monitor_init(void)
+{
+#ifdef HAVE_INOTIFY
+ monitor_type = ECORE_FILE_MONITOR_TYPE_INOTIFY;
+ if (ecore_file_monitor_inotify_init())
+ return 1;
+#endif
+#ifdef HAVE_NOTIFY_WIN32
+ monitor_type = ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32;
+ if (ecore_file_monitor_win32_init())
+ return 1;
+#endif
+#ifdef HAVE_POLL
+ monitor_type = ECORE_FILE_MONITOR_TYPE_POLL;
+ if (ecore_file_monitor_poll_init())
+ return 1;
+#endif
+ monitor_type = ECORE_FILE_MONITOR_TYPE_NONE;
+ return 0;
+}
+
+void
+ecore_file_monitor_shutdown(void)
+{
+ switch (monitor_type)
+ {
+ case ECORE_FILE_MONITOR_TYPE_NONE:
+ break;
+#ifdef HAVE_INOTIFY
+ case ECORE_FILE_MONITOR_TYPE_INOTIFY:
+ ecore_file_monitor_inotify_shutdown();
+ break;
+#endif
+#ifdef HAVE_NOTIFY_WIN32
+ case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
+ ecore_file_monitor_win32_shutdown();
+ break;
+#endif
+#ifdef HAVE_POLL
+ case ECORE_FILE_MONITOR_TYPE_POLL:
+ ecore_file_monitor_poll_shutdown();
+ break;
+#endif
+ }
+}
+
+/**
+ * Monitor a path using inotify or polling
+ * @param path The path to monitor
+ * @param func The function to call on changes
+ * @param data The data passed to func
+ * @return An Ecore_File_Monitor pointer or NULL on failure
+ */
+EAPI Ecore_File_Monitor *
+ecore_file_monitor_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
+{
+ switch (monitor_type)
+ {
+ case ECORE_FILE_MONITOR_TYPE_NONE:
+ return NULL;
+#ifdef HAVE_INOTIFY
+ case ECORE_FILE_MONITOR_TYPE_INOTIFY:
+ return ecore_file_monitor_inotify_add(path, func, data);
+#endif
+#ifdef HAVE_NOTIFY_WIN32
+ case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
+ return ecore_file_monitor_win32_add(path, func, data);
+#endif
+#ifdef HAVE_POLL
+ case ECORE_FILE_MONITOR_TYPE_POLL:
+ return ecore_file_monitor_poll_add(path, func, data);
+#endif
+ }
+ return NULL;
+}
+
+/**
+ * Stop monitoring a path
+ * @param em The Ecore_File_Monitor to stop
+ */
+EAPI void
+ecore_file_monitor_del(Ecore_File_Monitor *em)
+{
+ switch (monitor_type)
+ {
+ case ECORE_FILE_MONITOR_TYPE_NONE:
+ break;
+#ifdef HAVE_INOTIFY
+ case ECORE_FILE_MONITOR_TYPE_INOTIFY:
+ ecore_file_monitor_inotify_del(em);
+ break;
+#endif
+#ifdef HAVE_NOTIFY_WIN32
+ case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
+ ecore_file_monitor_win32_del(em);
+ break;
+#endif
+#ifdef HAVE_POLL
+ case ECORE_FILE_MONITOR_TYPE_POLL:
+ ecore_file_monitor_poll_del(em);
+ break;
+#endif
+ }
+}
+
+/**
+ * Get the monitored path
+ * @param em The Ecore_File_Monitor to query
+ * @return The path that is monitored by @p em
+ */
+EAPI const char *
+ecore_file_monitor_path_get(Ecore_File_Monitor *em)
+{
+ return em->path;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ecore_file_private.h"
+
+/*
+ * TODO:
+ *
+ * - Listen to these events:
+ * IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_OPEN
+ * - Read all events first, then call the callbacks. This will prevent several
+ * callbacks with the typic save cycle (delete file, new file)
+ */
+
+#ifdef HAVE_INOTIFY
+
+#ifdef HAVE_SYS_INOTIFY
+# include <sys/inotify.h>
+#else
+# include <asm/unistd.h>
+# include <linux/inotify.h>
+#endif
+
+#ifndef HAVE_SYS_INOTIFY
+static inline int inotify_init(void);
+static inline int inotify_add_watch(int fd, const char *name, __u32 mask);
+static inline int inotify_rm_watch(int fd, __u32 wd);
+#endif
+
+
+typedef struct _Ecore_File_Monitor_Inotify Ecore_File_Monitor_Inotify;
+
+#define ECORE_FILE_MONITOR_INOTIFY(x) ((Ecore_File_Monitor_Inotify *)(x))
+
+struct _Ecore_File_Monitor_Inotify
+{
+ Ecore_File_Monitor monitor;
+ int wd;
+};
+
+static Ecore_Fd_Handler *_fdh = NULL;
+static Ecore_File_Monitor *_monitors = NULL;
+
+static int _ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh);
+static Ecore_File_Monitor *_ecore_file_monitor_inotify_monitor_find(int wd);
+static void _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask);
+static int _ecore_file_monitor_inotify_monitor(Ecore_File_Monitor *em, const char *path);
+#if 0
+static void _ecore_file_monitor_inotify_print(char *file, int mask);
+#endif
+
+int
+ecore_file_monitor_inotify_init(void)
+{
+ int fd;
+
+ fd = inotify_init();
+ if (fd < 0)
+ return 0;
+
+ _fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_file_monitor_inotify_handler,
+ NULL, NULL, NULL);
+ if (!_fdh)
+ {
+ close(fd);
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+ecore_file_monitor_inotify_shutdown(void)
+{
+ int fd;
+
+ while(_monitors)
+ ecore_file_monitor_inotify_del(_monitors);
+
+ if (_fdh)
+ {
+ fd = ecore_main_fd_handler_fd_get(_fdh);
+ ecore_main_fd_handler_del(_fdh);
+ close(fd);
+ }
+ return 1;
+}
+
+Ecore_File_Monitor *
+ecore_file_monitor_inotify_add(const char *path,
+ void (*func) (void *data, Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
+{
+ Ecore_File_Monitor *em;
+ int len;
+
+ em = calloc(1, sizeof(Ecore_File_Monitor_Inotify));
+ if (!em) return NULL;
+
+ em->func = func;
+ em->data = data;
+
+ em->path = strdup(path);
+ len = strlen(em->path);
+ if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
+ em->path[len - 1] = 0;
+
+ _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
+
+ if (ecore_file_exists(em->path))
+ {
+ if (!_ecore_file_monitor_inotify_monitor(em, em->path))
+ return NULL;
+ }
+ else
+ {
+ ecore_file_monitor_inotify_del(em);
+ return NULL;
+ }
+
+ return em;
+}
+
+void
+ecore_file_monitor_inotify_del(Ecore_File_Monitor *em)
+{
+ int fd;
+
+ _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
+
+ fd = ecore_main_fd_handler_fd_get(_fdh);
+ if (ECORE_FILE_MONITOR_INOTIFY(em)->wd)
+ inotify_rm_watch(fd, ECORE_FILE_MONITOR_INOTIFY(em)->wd);
+ free(em->path);
+ free(em);
+}
+
+static int
+_ecore_file_monitor_inotify_handler(void *data __UNUSED__, Ecore_Fd_Handler *fdh)
+{
+ Ecore_File_Monitor *em;
+ char buffer[16384];
+ struct inotify_event *event;
+ int i = 0;
+ int event_size;
+ ssize_t size;
+
+ size = read(ecore_main_fd_handler_fd_get(fdh), buffer, sizeof(buffer));
+ while (i < size)
+ {
+ event = (struct inotify_event *)&buffer[i];
+ event_size = sizeof(struct inotify_event) + event->len;
+ i += event_size;
+
+ em = _ecore_file_monitor_inotify_monitor_find(event->wd);
+ if (!em) continue;
+
+ _ecore_file_monitor_inotify_events(em, (event->len ? event->name : NULL), event->mask);
+ }
+
+ return 1;
+}
+
+static Ecore_File_Monitor *
+_ecore_file_monitor_inotify_monitor_find(int wd)
+{
+ Ecore_File_Monitor *l;
+
+ EINA_INLIST_FOREACH(_monitors, l)
+ {
+ if (ECORE_FILE_MONITOR_INOTIFY(l)->wd == wd)
+ return l;
+ }
+ return NULL;
+}
+
+static void
+_ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask)
+{
+ char buf[PATH_MAX];
+ int isdir;
+
+ if ((file) && (file[0]))
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
+ else
+ strcpy(buf, em->path);
+ isdir = mask & IN_ISDIR;
+
+#if 0
+ _ecore_file_monitor_inotify_print(file, mask);
+#endif
+
+ if (mask & IN_MODIFY)
+ {
+ if (!isdir)
+ em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
+ }
+ if (mask & IN_MOVED_FROM)
+ {
+ if (isdir)
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf);
+ else
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf);
+ }
+ if (mask & IN_MOVED_TO)
+ {
+ if (isdir)
+ em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf);
+ else
+ em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf);
+ }
+ if (mask & IN_DELETE)
+ {
+ if (isdir)
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf);
+ else
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf);
+ }
+ if (mask & IN_CREATE)
+ {
+ if (isdir)
+ em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf);
+ else
+ em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf);
+ }
+ if (mask & IN_DELETE_SELF)
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ }
+ if (mask & IN_MOVE_SELF)
+ {
+ /* We just call delete. The dir is gone... */
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ }
+ if (mask & IN_UNMOUNT)
+ {
+ /* We just call delete. The dir is gone... */
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ }
+ if (mask & IN_IGNORED)
+ {
+ /* The watch is removed. If the file name still exists monitor the new one,
+ * else delete it */
+ if (ecore_file_exists(em->path))
+ {
+ if (!_ecore_file_monitor_inotify_monitor(em, em->path))
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ }
+ else
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ }
+}
+
+static int
+_ecore_file_monitor_inotify_monitor(Ecore_File_Monitor *em, const char *path)
+{
+ int mask;
+ mask = IN_MODIFY|
+ IN_MOVED_FROM|IN_MOVED_TO|
+ IN_DELETE|IN_CREATE|
+ IN_DELETE_SELF|IN_MOVE_SELF|
+ IN_UNMOUNT;
+ ECORE_FILE_MONITOR_INOTIFY(em)->wd = inotify_add_watch(ecore_main_fd_handler_fd_get(_fdh),
+ path, mask);
+ if (ECORE_FILE_MONITOR_INOTIFY(em)->wd < 0)
+ {
+ ERR("inotify_add_watch error");
+ ecore_file_monitor_inotify_del(em);
+ return 0;
+ }
+ return 1;
+}
+
+#ifndef HAVE_SYS_INOTIFY
+static inline int
+inotify_init(void)
+{
+ return syscall(__NR_inotify_init);
+}
+
+static inline int
+inotify_add_watch(int fd, const char *name, __u32 mask)
+{
+ return syscall(__NR_inotify_add_watch, fd, name, mask);
+}
+
+static inline int
+inotify_rm_watch(int fd, __u32 wd)
+{
+ return syscall(__NR_inotify_rm_watch, fd, wd);
+}
+#endif
+
+#if 0
+static void
+_ecore_file_monitor_inotify_print(char *file, int mask)
+{
+ const char *type;
+
+ if (mask & IN_ISDIR)
+ type = "dir";
+ else
+ type = "file";
+
+ if (mask & IN_MODIFY)
+ {
+ WRN("Inotify modified %s: %s", type, file);
+ }
+ if (mask & IN_MOVED_FROM)
+ {
+ WRN("Inotify moved from %s: %s", type, file);
+ }
+ if (mask & IN_MOVED_TO)
+ {
+ WRN("Inotify moved to %s: %s", type, file);
+ }
+ if (mask & IN_DELETE)
+ {
+ WRN("Inotify delete %s: %s", type, file);
+ }
+ if (mask & IN_CREATE)
+ {
+ WRN("Inotify create %s: %s", type, file);
+ }
+ if (mask & IN_DELETE_SELF)
+ {
+ WRN("Inotify delete self %s: %s", type, file);
+ }
+ if (mask & IN_MOVE_SELF)
+ {
+ WRN("Inotify move self %s: %s", type, file);
+ }
+ if (mask & IN_UNMOUNT)
+ {
+ WRN("Inotify unmount %s: %s", type, file);
+ }
+}
+#endif
+#endif /* HAVE_INOTIFY */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ecore_file_private.h"
+
+#ifdef HAVE_POLL
+
+/*
+ * TODO:
+ * - Implement recursive as an option!
+ * - Keep whole path or just name of file? (Memory or CPU...)
+ * - Remove requests without files?
+ * - Change poll time
+ */
+
+typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll;
+
+#define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x))
+
+struct _Ecore_File_Monitor_Poll
+{
+ Ecore_File_Monitor monitor;
+ int mtime;
+ unsigned char deleted;
+};
+
+#define ECORE_FILE_INTERVAL_MIN 1.0
+#define ECORE_FILE_INTERVAL_STEP 0.5
+#define ECORE_FILE_INTERVAL_MAX 5.0
+
+static double _interval = ECORE_FILE_INTERVAL_MIN;
+static Ecore_Timer *_timer = NULL;
+static Ecore_File_Monitor *_monitors = NULL;
+static int _lock = 0;
+
+static int _ecore_file_monitor_poll_handler(void *data);
+static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em);
+static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name);
+
+int
+ecore_file_monitor_poll_init(void)
+{
+ return 1;
+}
+
+int
+ecore_file_monitor_poll_shutdown(void)
+{
+ while(_monitors)
+ ecore_file_monitor_poll_del(_monitors);
+
+ if (_timer)
+ {
+ ecore_timer_del(_timer);
+ _timer = NULL;
+ }
+ return 1;
+}
+
+Ecore_File_Monitor *
+ecore_file_monitor_poll_add(const char *path,
+ void (*func) (void *data, Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
+{
+ Ecore_File_Monitor *em;
+ size_t len;
+
+ if (!path) return NULL;
+ if (!func) return NULL;
+
+ em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
+ if (!em) return NULL;
+
+ if (!_timer)
+ _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
+ else
+ ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
+
+ em->path = strdup(path);
+ len = strlen(em->path);
+ if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
+ em->path[len - 1] = 0;
+
+ em->func = func;
+ em->data = data;
+
+ ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
+ if (ecore_file_exists(em->path))
+ {
+ if (ecore_file_is_dir(em->path))
+ {
+ /* Check for subdirs */
+ Eina_List *files;
+ char *file;
+
+ files = ecore_file_ls(em->path);
+ EINA_LIST_FREE(files, file)
+ {
+ Ecore_File *f;
+ char buf[PATH_MAX];
+
+ f = calloc(1, sizeof(Ecore_File));
+ if (!f)
+ {
+ free(file);
+ continue;
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
+ f->name = file;
+ f->mtime = ecore_file_mod_time(buf);
+ f->is_dir = ecore_file_is_dir(buf);
+ em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
+ }
+ }
+ }
+ else
+ {
+ ecore_file_monitor_poll_del(em);
+ return NULL;
+ }
+
+ _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
+
+ return em;
+}
+
+void
+ecore_file_monitor_poll_del(Ecore_File_Monitor *em)
+{
+ Ecore_File *l;
+
+ if (_lock)
+ {
+ ECORE_FILE_MONITOR_POLL(em)->deleted = 1;
+ return;
+ }
+
+ /* Remove files */
+ /*It's possible there weren't any files to monitor, so check if the list is init*/
+ if (em->files)
+ {
+ for (l = em->files; l;)
+ {
+ Ecore_File *file = l;
+
+ l = (Ecore_File *) EINA_INLIST_GET(l)->next;
+ free(file->name);
+ free(file);
+ }
+ }
+
+ if (_monitors)
+ _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
+
+ free(em->path);
+ free(em);
+
+ if (_timer)
+ {
+ if (!_monitors)
+ {
+ ecore_timer_del(_timer);
+ _timer = NULL;
+ }
+ else
+ ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
+ }
+}
+
+static int
+_ecore_file_monitor_poll_handler(void *data __UNUSED__)
+{
+ Ecore_File_Monitor *l;
+
+ _interval += ECORE_FILE_INTERVAL_STEP;
+
+ _lock = 1;
+ EINA_INLIST_FOREACH(_monitors, l)
+ _ecore_file_monitor_poll_check(l);
+ _lock = 0;
+
+ if (_interval > ECORE_FILE_INTERVAL_MAX)
+ _interval = ECORE_FILE_INTERVAL_MAX;
+ ecore_timer_interval_set(_timer, _interval);
+
+ for (l = _monitors; l;)
+ {
+ Ecore_File_Monitor *em = l;
+
+ l = ECORE_FILE_MONITOR(EINA_INLIST_GET(l)->next);
+ if (ECORE_FILE_MONITOR_POLL(em)->deleted)
+ ecore_file_monitor_del(em);
+ }
+ return 1;
+}
+
+static void
+_ecore_file_monitor_poll_check(Ecore_File_Monitor *em)
+{
+ int mtime;
+
+ mtime = ecore_file_mod_time(em->path);
+ if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime)
+ {
+ Ecore_File *l;
+ Ecore_File_Event event;
+
+ /* Notify all files deleted */
+ for (l = em->files; l;)
+ {
+ Ecore_File *f = l;
+ char buf[PATH_MAX];
+
+ l = (Ecore_File *) EINA_INLIST_GET(l)->next;
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
+ if (f->is_dir)
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
+ else
+ event = ECORE_FILE_EVENT_DELETED_FILE;
+ em->func(em->data, em, event, buf);
+ free(f->name);
+ free(f);
+ }
+ em->files = NULL;
+ em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ }
+ else
+ {
+ Ecore_File *l;
+
+ /* Check for changed files */
+ for (l = em->files; l;)
+ {
+ Ecore_File *f = l;
+ char buf[PATH_MAX];
+ int mtime;
+ Ecore_File_Event event;
+
+ l = (Ecore_File *) EINA_INLIST_GET(l)->next;
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
+ mtime = ecore_file_mod_time(buf);
+ if (mtime < f->mtime)
+ {
+ if (f->is_dir)
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
+ else
+ event = ECORE_FILE_EVENT_DELETED_FILE;
+
+ em->func(em->data, em, event, buf);
+ em->files = (Ecore_File *) eina_inlist_remove(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
+ free(f->name);
+ free(f);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ }
+ else if ((mtime > f->mtime) && !(f->is_dir))
+ {
+ em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ f->mtime = mtime;
+ }
+ else
+ f->mtime = mtime;
+ }
+
+ /* Check for new files */
+ if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime)
+ {
+ Eina_List *files;
+ Eina_List *l;
+ char *file;
+
+ /* Files have been added or removed */
+ files = ecore_file_ls(em->path);
+ if (files)
+ {
+ /* Are we a directory? We should check first, rather than rely on null here*/
+ EINA_LIST_FOREACH(files, l, file)
+ {
+ Ecore_File *f;
+ char buf[PATH_MAX];
+ Ecore_File_Event event;
+
+ if (_ecore_file_monitor_poll_checking(em, file))
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
+ f = calloc(1, sizeof(Ecore_File));
+ if (!f)
+ continue;
+
+ f->name = strdup(file);
+ f->mtime = ecore_file_mod_time(buf);
+ f->is_dir = ecore_file_mod_time(buf);
+ if (f->is_dir)
+ event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
+ else
+ event = ECORE_FILE_EVENT_CREATED_FILE;
+ em->func(em->data, em, event, buf);
+ em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
+ }
+ while (files)
+ {
+ file = eina_list_data_get(files);
+ free(file);
+ files = eina_list_remove_list(files, files);
+ }
+ }
+
+ if (!ecore_file_is_dir(em->path))
+ em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path);
+ _interval = ECORE_FILE_INTERVAL_MIN;
+ }
+ }
+ ECORE_FILE_MONITOR_POLL(em)->mtime = mtime;
+}
+
+static int
+_ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name)
+{
+ Ecore_File *l;
+
+ EINA_INLIST_FOREACH(em->files, l)
+ {
+ if (!strcmp(l->name, name))
+ return 1;
+ }
+ return 0;
+}
+#endif
--- /dev/null
+/*\r
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2\r
+ */\r
+\r
+#ifdef HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif\r
+\r
+#ifdef HAVE_NOTIFY_WIN32\r
+\r
+# define WIN32_LEAN_AND_MEAN\r
+# include <windows.h>\r
+# undef WIN32_LEAN_AND_MEAN\r
+# include <process.h>\r
+\r
+# include "ecore_file_private.h"\r
+\r
+\r
+typedef struct _Ecore_File_Monitor_Win32 Ecore_File_Monitor_Win32;\r
+typedef struct _Ecore_File_Monitor_Win32_Data Ecore_File_Monitor_Win32_Data;\r
+\r
+/* 4096 = 256 * sizeof(FILE_NOTIFY_INFORMATION) */\r
+# define ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE 4096\r
+# define ECORE_FILE_MONITOR_WIN32(x) ((Ecore_File_Monitor_Win32 *)(x))\r
+\r
+struct _Ecore_File_Monitor_Win32_Data\r
+{\r
+ char buffer[ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE];\r
+ OVERLAPPED overlapped;\r
+ HANDLE handle;\r
+ HANDLE event;\r
+ Ecore_File_Monitor *monitor;\r
+ Ecore_Win32_Handler *h;\r
+ DWORD buf_length;\r
+ int is_dir;\r
+};\r
+\r
+struct _Ecore_File_Monitor_Win32\r
+{\r
+ Ecore_File_Monitor monitor;\r
+ Ecore_File_Monitor_Win32_Data *file;\r
+ Ecore_File_Monitor_Win32_Data *dir;\r
+};\r
+\r
+static Ecore_File_Monitor *_monitors = NULL;\r
+\r
+static int _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh);\r
+\r
+\r
+static Ecore_File_Monitor_Win32_Data *\r
+_ecore_file_monitor_win32_data_new(Ecore_File_Monitor *monitor, int type)\r
+{\r
+ Ecore_File_Monitor_Win32_Data *md;\r
+ DWORD filter;\r
+\r
+ md = (Ecore_File_Monitor_Win32_Data *)calloc(1, sizeof(Ecore_File_Monitor_Win32_Data));\r
+ if (!md) return NULL;\r
+\r
+ md->handle = CreateFile(monitor->path,\r
+ FILE_LIST_DIRECTORY,\r
+ FILE_SHARE_READ |\r
+ FILE_SHARE_WRITE,\r
+ NULL,\r
+ OPEN_EXISTING,\r
+ FILE_FLAG_BACKUP_SEMANTICS |\r
+ FILE_FLAG_OVERLAPPED,\r
+ NULL);\r
+ if (md->handle == INVALID_HANDLE_VALUE)\r
+ goto free_md;\r
+\r
+ md->event = CreateEvent(NULL, FALSE, FALSE, NULL);\r
+ if (!md->event)\r
+ goto close_handle;\r
+\r
+ ZeroMemory (&md->overlapped, sizeof(md->overlapped));\r
+ md->overlapped.hEvent = md->event;\r
+\r
+ filter = (type == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;\r
+ filter |=\r
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |\r
+ FILE_NOTIFY_CHANGE_SIZE |\r
+ FILE_NOTIFY_CHANGE_LAST_WRITE |\r
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |\r
+ FILE_NOTIFY_CHANGE_CREATION |\r
+ FILE_NOTIFY_CHANGE_SECURITY;\r
+\r
+ if (!ReadDirectoryChangesW(md->handle,\r
+ md->buffer,\r
+ ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,\r
+ FALSE,\r
+ filter,\r
+ &md->buf_length,\r
+ &md->overlapped,\r
+ NULL))\r
+ goto close_event;\r
+\r
+ md->h = ecore_main_win32_handler_add(md->event,\r
+ _ecore_file_monitor_win32_cb,\r
+ md);\r
+ if (!md->h)\r
+ goto close_event;\r
+\r
+ md->monitor = monitor;\r
+ md->is_dir = type;\r
+\r
+ return md;\r
+\r
+ close_event:\r
+ CloseHandle(md->event);\r
+ close_handle:\r
+ CloseHandle(md->handle);\r
+ free_md:\r
+ free(md);\r
+\r
+ return NULL;\r
+}\r
+\r
+static void\r
+_ecore_file_monitor_win32_data_free(Ecore_File_Monitor_Win32_Data *md)\r
+{\r
+ if (!md) return;\r
+\r
+ CloseHandle(md->event);\r
+ CloseHandle (md->handle);\r
+ free (md);\r
+}\r
+\r
+static int\r
+_ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh)\r
+{\r
+ char filename[PATH_MAX];\r
+ PFILE_NOTIFY_INFORMATION fni;\r
+ Ecore_File_Monitor_Win32_Data *md;\r
+ wchar_t *wname;\r
+ char *name;\r
+ DWORD filter;\r
+ DWORD offset;\r
+ DWORD buf_length;\r
+ Ecore_File_Event event = ECORE_FILE_EVENT_NONE;\r
+\r
+ md = (Ecore_File_Monitor_Win32_Data *)data;\r
+\r
+ if (!GetOverlappedResult (md->handle, &md->overlapped, &buf_length, TRUE))\r
+ return 1;\r
+\r
+ fni = (PFILE_NOTIFY_INFORMATION)md->buffer;\r
+ do {\r
+ if (!fni)\r
+ break;\r
+ offset = fni->NextEntryOffset;\r
+\r
+ wname = (wchar_t *)malloc(sizeof(wchar_t) * (fni->FileNameLength + 1));\r
+ if (!wname)\r
+ return 0;\r
+\r
+ memcpy(wname, fni->FileName, fni->FileNameLength);\r
+ wname[fni->FileNameLength]='\0';\r
+ name = evil_wchar_to_char(wname);\r
+ free(wname);\r
+ if (!name)\r
+ return 0;\r
+\r
+ _snprintf(filename, PATH_MAX, "%s\\%s", md->monitor->path, name);\r
+ free(name);\r
+\r
+ switch (fni->Action)\r
+ {\r
+ case FILE_ACTION_ADDED:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_CREATED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_CREATED_FILE;\r
+ break;\r
+ case FILE_ACTION_REMOVED:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_DELETED_FILE;\r
+ break;\r
+ case FILE_ACTION_MODIFIED:\r
+ if (!md->is_dir)\r
+ event = ECORE_FILE_EVENT_MODIFIED;\r
+ break;\r
+ case FILE_ACTION_RENAMED_OLD_NAME:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_DELETED_FILE;\r
+ break;\r
+ case FILE_ACTION_RENAMED_NEW_NAME:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_CREATED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_CREATED_FILE;\r
+ break;\r
+ default: \r
+ fprintf(stderr, "unknown event\n");\r
+ event = ECORE_FILE_EVENT_NONE;\r
+ break;\r
+ }\r
+ if (event != ECORE_FILE_EVENT_NONE)\r
+ md->monitor->func(md->monitor->data, md->monitor, event, filename);\r
+\r
+ fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE)fni + offset);\r
+ } while (offset);\r
+\r
+ filter = (md->is_dir == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;\r
+ filter |=\r
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |\r
+ FILE_NOTIFY_CHANGE_SIZE |\r
+ FILE_NOTIFY_CHANGE_LAST_WRITE |\r
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |\r
+ FILE_NOTIFY_CHANGE_CREATION |\r
+ FILE_NOTIFY_CHANGE_SECURITY;\r
+\r
+ ReadDirectoryChangesW(md->handle,\r
+ md->buffer,\r
+ ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,\r
+ FALSE,\r
+ filter,\r
+ &md->buf_length,\r
+ &md->overlapped,\r
+ NULL);\r
+ return 1;\r
+}\r
+\r
+int\r
+ecore_file_monitor_win32_init(void)\r
+{\r
+ return 1;\r
+}\r
+\r
+int\r
+ecore_file_monitor_win32_shutdown(void)\r
+{\r
+ return 1;\r
+}\r
+\r
+Ecore_File_Monitor *\r
+ecore_file_monitor_win32_add(const char *path,\r
+ void (*func) (void *data, Ecore_File_Monitor *em,\r
+ Ecore_File_Event event,\r
+ const char *path),\r
+ void *data)\r
+{\r
+ Ecore_File_Monitor_Win32 *m;\r
+ Ecore_File_Monitor *em;\r
+ size_t len;\r
+\r
+ if (!path || (*path == '\0')) return NULL;\r
+ if (!ecore_file_exists(path) || !ecore_file_is_dir(path))\r
+ return NULL;\r
+ if (!func) return NULL;\r
+\r
+ em = (Ecore_File_Monitor *)calloc(1, sizeof(Ecore_File_Monitor_Win32));\r
+ if (!em) return NULL;\r
+\r
+ em->func = func;\r
+ em->data = data;\r
+\r
+ em->path = strdup(path);\r
+ if (!em->path)\r
+ {\r
+ free(em);\r
+ return NULL;\r
+ }\r
+ len = strlen(em->path);\r
+ if (em->path[len - 1] == '/' || em->path[len - 1] == '\\')\r
+ em->path[len - 1] = '\0';\r
+\r
+ m = ECORE_FILE_MONITOR_WIN32(em);\r
+\r
+ m->file = _ecore_file_monitor_win32_data_new(em, 0);\r
+ if (!m->file)\r
+ {\r
+ free(em->path);\r
+ free(em);\r
+ return NULL;\r
+ }\r
+\r
+ m->dir = _ecore_file_monitor_win32_data_new(em, 1);\r
+ if (!m->dir)\r
+ {\r
+ _ecore_file_monitor_win32_data_free(m->file);\r
+ free(em->path);\r
+ free(em);\r
+ return NULL;\r
+ }\r
+\r
+ _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));\r
+\r
+ return em;\r
+}\r
+\r
+void\r
+ecore_file_monitor_win32_del(Ecore_File_Monitor *em)\r
+{\r
+ Ecore_File_Monitor_Win32 *m;\r
+\r
+ if (!em)\r
+ return;\r
+\r
+ m = ECORE_FILE_MONITOR_WIN32(em);\r
+ _ecore_file_monitor_win32_data_free(m->dir);\r
+ _ecore_file_monitor_win32_data_free(m->file);\r
+ free(em->path);\r
+ free(em);\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ecore_file_private.h"
+
+static Eina_List *__ecore_file_path_bin = NULL;
+
+static Eina_List *_ecore_file_path_from_env(const char *env);
+
+void
+ecore_file_path_init(void)
+{
+ __ecore_file_path_bin = _ecore_file_path_from_env("PATH");
+}
+
+void
+ecore_file_path_shutdown(void)
+{
+ char *dir;
+
+ EINA_LIST_FREE(__ecore_file_path_bin, dir)
+ free(dir);
+}
+
+Eina_List *
+_ecore_file_path_from_env(const char *env)
+{
+ Eina_List *path = NULL;
+ char *env_path, *p, *last;
+
+ env_path = getenv(env);
+ if (!env_path)
+ return path;
+
+ env_path = strdup(env_path);
+ last = env_path;
+ for (p = env_path; *p; p++)
+ {
+ if (*p == ':')
+ *p = '\0';
+
+ if (!*p)
+ {
+ if (!ecore_file_path_dir_exists(last))
+ path = eina_list_append(path, strdup(last));
+ last = p + 1;
+ }
+ }
+ if (p > last)
+ path = eina_list_append(path, strdup(last));
+
+ free(env_path);
+ return path;
+}
+
+/**
+ * Check if the given directory is in PATH
+ * @param The name of the directory to search in PATH
+ * @return 1 if the directory exist in PATH, 0 otherwise
+ */
+EAPI int
+ecore_file_path_dir_exists(const char *in_dir)
+{
+ Eina_List *l;
+ char *dir;
+
+ if (!__ecore_file_path_bin) return 0;
+ EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
+ {
+ if (strcmp(dir, in_dir))
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check if the given application is installed
+ * @param exe The name of the application
+ * @return 1 if the exe is in PATH and is executable
+ *
+ * This function check if the given name exist in PATH and is executable
+ */
+EAPI int
+ecore_file_app_installed(const char *exe)
+{
+ Eina_List *l;
+ char *dir;
+ char buf[PATH_MAX];
+
+ if (!exe) return 0;
+ if (ecore_file_can_exec(exe)) return 1;
+
+ EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
+ {
+ snprintf(buf, sizeof(buf), "%s/%s", dir, exe);
+ if (ecore_file_can_exec(buf))
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Get a list of all the applications installed on the system
+ * @return An Eina_List containing all the executable files in the system
+ */
+EAPI Eina_List *
+ecore_file_app_list(void)
+{
+ Eina_List *list = NULL;
+ Eina_List *files;
+ Eina_List *l;
+ char buf[PATH_MAX], *dir, *exe;
+
+ EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
+ {
+ files = ecore_file_ls(dir);
+ EINA_LIST_FREE(files, exe)
+ {
+ snprintf(buf, sizeof(buf), "%s/%s", dir, exe);
+ if ((ecore_file_can_exec(buf)) &&
+ (!ecore_file_is_dir(buf)))
+ list = eina_list_append(list, strdup(buf));
+ free(exe);
+ }
+ }
+
+ return list;
+}
--- /dev/null
+#ifndef ECORE_FILE_PRIVATE_H_
+#define ECORE_FILE_PRIVATE_H_
+
+#ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+#endif
+
+#ifdef __linux__
+# include <features.h>
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#include "Ecore_File.h"
+
+extern int _ecore_file_log_dom;
+
+#ifdef ECORE_FILE_DEFAULT_LOG_COLOR
+#undef ECORE_FILE_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_FILE_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_file_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_file_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_file_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_file_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_file_log_dom, __VA_ARGS__)
+
+/* ecore_file_monitor */
+int ecore_file_monitor_init(void);
+void ecore_file_monitor_shutdown(void);
+
+#define ECORE_FILE_MONITOR(x) ((Ecore_File_Monitor *)(x))
+
+typedef struct _Ecore_File Ecore_File;
+struct _Ecore_File
+{
+ EINA_INLIST;
+ char *name;
+ int mtime;
+ unsigned char is_dir;
+};
+
+struct _Ecore_File_Monitor
+{
+ EINA_INLIST;
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path);
+
+ char *path;
+ void *data;
+ Ecore_File *files;
+};
+
+#ifdef HAVE_INOTIFY
+int ecore_file_monitor_inotify_init(void);
+int ecore_file_monitor_inotify_shutdown(void);
+Ecore_File_Monitor *ecore_file_monitor_inotify_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+void ecore_file_monitor_inotify_del(Ecore_File_Monitor *ecore_file_monitor);
+#endif
+
+#ifdef HAVE_NOTIFY_WIN32
+int ecore_file_monitor_win32_init(void);
+int ecore_file_monitor_win32_shutdown(void);
+Ecore_File_Monitor *ecore_file_monitor_win32_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+void ecore_file_monitor_win32_del(Ecore_File_Monitor *ecore_file_monitor);
+#endif
+
+#ifdef HAVE_POLL
+int ecore_file_monitor_poll_init(void);
+int ecore_file_monitor_poll_shutdown(void);
+Ecore_File_Monitor *ecore_file_monitor_poll_add(const char *path,
+ void (*func) (void *data,
+ Ecore_File_Monitor *ecore_file_monitor,
+ Ecore_File_Event event,
+ const char *path),
+ void *data);
+void ecore_file_monitor_poll_del(Ecore_File_Monitor *ecore_file_monitor);
+
+#endif
+
+/* ecore_file_path */
+void ecore_file_path_init(void);
+void ecore_file_path_shutdown(void);
+
+/* ecore_file_download */
+int ecore_file_download_init(void);
+void ecore_file_download_shutdown(void);
+
+#endif
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef _ECORE_IMF_H
+#define _ECORE_IMF_H
+
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_IMF_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_IMF_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Events sent by the Input Method */
+ typedef struct _Ecore_IMF_Event_Preedit_Start Ecore_IMF_Event_Preedit_Start;
+ typedef struct _Ecore_IMF_Event_Preedit_End Ecore_IMF_Event_Preedit_End;
+ typedef struct _Ecore_IMF_Event_Preedit_Changed Ecore_IMF_Event_Preedit_Changed;
+ typedef struct _Ecore_IMF_Event_Commit Ecore_IMF_Event_Commit;
+ typedef struct _Ecore_IMF_Event_Delete_Surrounding Ecore_IMF_Event_Delete_Surrounding;
+
+ /* Events to filter */
+ typedef struct _Ecore_IMF_Event_Mouse_Down Ecore_IMF_Event_Mouse_Down;
+ typedef struct _Ecore_IMF_Event_Mouse_Up Ecore_IMF_Event_Mouse_Up;
+ typedef struct _Ecore_IMF_Event_Mouse_In Ecore_IMF_Event_Mouse_In;
+ typedef struct _Ecore_IMF_Event_Mouse_Out Ecore_IMF_Event_Mouse_Out;
+ typedef struct _Ecore_IMF_Event_Mouse_Move Ecore_IMF_Event_Mouse_Move;
+ typedef struct _Ecore_IMF_Event_Mouse_Wheel Ecore_IMF_Event_Mouse_Wheel;
+ typedef struct _Ecore_IMF_Event_Key_Down Ecore_IMF_Event_Key_Down;
+ typedef struct _Ecore_IMF_Event_Key_Up Ecore_IMF_Event_Key_Up;
+ typedef union _Ecore_IMF_Event Ecore_IMF_Event;
+
+ typedef struct _Ecore_IMF_Context Ecore_IMF_Context; /**< An Input Method Context */
+ typedef struct _Ecore_IMF_Context_Class Ecore_IMF_Context_Class; /**< An Input Method Context class */
+ typedef struct _Ecore_IMF_Context_Info Ecore_IMF_Context_Info; /**< An Input Method Context info */
+
+ EAPI extern int ECORE_IMF_EVENT_PREEDIT_START;
+ EAPI extern int ECORE_IMF_EVENT_PREEDIT_END;
+ EAPI extern int ECORE_IMF_EVENT_PREEDIT_CHANGED;
+ EAPI extern int ECORE_IMF_EVENT_COMMIT;
+ EAPI extern int ECORE_IMF_EVENT_DELETE_SURROUNDING;
+
+ typedef enum
+ {
+ ECORE_IMF_EVENT_MOUSE_DOWN,
+ ECORE_IMF_EVENT_MOUSE_UP,
+ ECORE_IMF_EVENT_MOUSE_IN,
+ ECORE_IMF_EVENT_MOUSE_OUT,
+ ECORE_IMF_EVENT_MOUSE_MOVE,
+ ECORE_IMF_EVENT_MOUSE_WHEEL,
+ ECORE_IMF_EVENT_KEY_DOWN,
+ ECORE_IMF_EVENT_KEY_UP
+ } Ecore_IMF_Event_Type;
+
+ typedef enum
+ {
+ ECORE_IMF_KEYBOARD_MODIFIER_NONE = 0, /**< No active modifiers */
+ ECORE_IMF_KEYBOARD_MODIFIER_CTRL = 1 << 0, /**< "Control" is pressed */
+ ECORE_IMF_KEYBOARD_MODIFIER_ALT = 1 << 1, /**< "Alt" is pressed */
+ ECORE_IMF_KEYBOARD_MODIFIER_SHIFT = 1 << 2, /**< "Shift" is pressed */
+ ECORE_IMF_KEYBOARD_MODIFIER_WIN = 1 << 3 /**< "Win" (between "Ctrl" and "Alt") is pressed */
+ } Ecore_IMF_Keyboard_Modifiers;
+
+ typedef enum
+ {
+ ECORE_IMF_KEYBOARD_LOCK_NONE = 0, /**< No locks are active */
+ ECORE_IMF_KEYBOARD_LOCK_NUM = 1 << 0, /**< "Num" lock is active */
+ ECORE_IMF_KEYBOARD_LOCK_CAPS = 1 << 1, /**< "Caps" lock is active */
+ ECORE_IMF_KEYBOARD_LOCK_SCROLL = 1 << 2 /**< "Scroll" lock is active */
+ } Ecore_IMF_Keyboard_Locks;
+
+ typedef enum
+ {
+ ECORE_IMF_MOUSE_NONE = 0, /**< A single click */
+ ECORE_IMF_MOUSE_DOUBLE_CLICK = 1 << 0, /**< A double click */
+ ECORE_IMF_MOUSE_TRIPLE_CLICK = 1 << 1 /**< A triple click */
+ } Ecore_IMF_Mouse_Flags;
+
+ typedef enum
+ {
+ ECORE_IMF_INPUT_MODE_ALPHA = 1 << 0,
+ ECORE_IMF_INPUT_MODE_NUMERIC = 1 << 1,
+ ECORE_IMF_INPUT_MODE_SPECIAL = 1 << 2,
+ ECORE_IMF_INPUT_MODE_HEXA = 1 << 3,
+ ECORE_IMF_INPUT_MODE_TELE = 1 << 4,
+ ECORE_IMF_INPUT_MODE_FULL = (ECORE_IMF_INPUT_MODE_ALPHA | ECORE_IMF_INPUT_MODE_NUMERIC | ECORE_IMF_INPUT_MODE_SPECIAL),
+ ECORE_IMF_INPUT_MODE_INVISIBLE = 1 << 29,
+ ECORE_IMF_INPUT_MODE_AUTOCAP = 1 << 30
+ } Ecore_IMF_Input_Mode;
+
+ struct _Ecore_IMF_Event_Preedit_Start
+ {
+ Ecore_IMF_Context *ctx;
+ };
+
+ struct _Ecore_IMF_Event_Preedit_End
+ {
+ Ecore_IMF_Context *ctx;
+ };
+
+ struct _Ecore_IMF_Event_Preedit_Changed
+ {
+ Ecore_IMF_Context *ctx;
+ };
+
+ struct _Ecore_IMF_Event_Commit
+ {
+ Ecore_IMF_Context *ctx;
+ char *str;
+ };
+
+ struct _Ecore_IMF_Event_Delete_Surrounding
+ {
+ Ecore_IMF_Context *ctx;
+ int offset;
+ int n_chars;
+ };
+
+ struct _Ecore_IMF_Event_Mouse_Down
+ {
+ int button; /**< The button which has been pressed */
+ struct {
+ int x, y;
+ } output;
+ struct {
+ int x, y;
+ } canvas;
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ Ecore_IMF_Mouse_Flags flags; /**< The flags corresponding the mouse click (single, double or triple click) */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ struct _Ecore_IMF_Event_Mouse_Up
+ {
+ int button; /**< The button which has been pressed */
+ struct {
+ int x, y;
+ } output;
+ struct {
+ int x, y;
+ } canvas;
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ Ecore_IMF_Mouse_Flags flags; /**< The flags corresponding the mouse click (single, double or triple click) */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ struct _Ecore_IMF_Event_Mouse_In
+ {
+ int buttons;
+ struct {
+ int x, y;
+ } output;
+ struct {
+ int x, y;
+ } canvas;
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ struct _Ecore_IMF_Event_Mouse_Out
+ {
+ int buttons;
+ struct {
+ int x, y;
+ } output;
+ struct {
+ int x, y;
+ } canvas;
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ struct _Ecore_IMF_Event_Mouse_Move
+ {
+ int buttons;
+ struct {
+ struct {
+ int x, y;
+ } output;
+ struct {
+ int x, y;
+ } canvas;
+ } cur, prev;
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ struct _Ecore_IMF_Event_Mouse_Wheel
+ {
+ int direction; /* 0 = default up/down wheel */
+ int z; /* ...,-2,-1 = down, 1,2,... = up */
+ struct {
+ int x, y;
+ } output;
+ struct {
+ int x, y;
+ } canvas;
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ struct _Ecore_IMF_Event_Key_Down
+ {
+ const char *keyname; /**< The string name of the key pressed */
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ const char *key; /**< The logical key : (eg shift+1 == exclamation) */
+ const char *string; /**< A UTF8 string if this keystroke has produced a visible string to be ADDED */
+ const char *compose; /**< A UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ struct _Ecore_IMF_Event_Key_Up
+ {
+ const char *keyname; /**< The string name of the key pressed */
+ Ecore_IMF_Keyboard_Modifiers modifiers; /**< The keyboard modifiers active when the event has been emitted */
+ Ecore_IMF_Keyboard_Locks locks; /**< The keyboard locks active when the event has been emitted */
+ const char *key; /**< The logical key : (eg shift+1 == exclamation) */
+ const char *string; /**< A UTF8 string if this keystroke has produced a visible string to be ADDED */
+ const char *compose; /**< A UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
+ unsigned int timestamp; /**< The timestamp when the event occured */
+ };
+
+ union _Ecore_IMF_Event
+ {
+ Ecore_IMF_Event_Mouse_Down mouse_down;
+ Ecore_IMF_Event_Mouse_Up mouse_up;
+ Ecore_IMF_Event_Mouse_In mouse_in;
+ Ecore_IMF_Event_Mouse_Out mouse_out;
+ Ecore_IMF_Event_Mouse_Move mouse_move;
+ Ecore_IMF_Event_Mouse_Wheel mouse_wheel;
+ Ecore_IMF_Event_Key_Down key_down;
+ Ecore_IMF_Event_Key_Up key_up;
+ };
+
+ struct _Ecore_IMF_Context_Class
+ {
+ void (*add) (Ecore_IMF_Context *ctx);
+ void (*del) (Ecore_IMF_Context *ctx);
+ void (*client_window_set) (Ecore_IMF_Context *ctx, void *window);
+ void (*client_canvas_set) (Ecore_IMF_Context *ctx, void *canvas);
+ void (*show) (Ecore_IMF_Context *ctx);
+ void (*hide) (Ecore_IMF_Context *ctx);
+ void (*preedit_string_get) (Ecore_IMF_Context *ctx, char **str, int *cursor_pos);
+ void (*focus_in) (Ecore_IMF_Context *ctx);
+ void (*focus_out) (Ecore_IMF_Context *ctx);
+ void (*reset) (Ecore_IMF_Context *ctx);
+ void (*cursor_position_set) (Ecore_IMF_Context *ctx, int cursor_pos);
+ void (*use_preedit_set) (Ecore_IMF_Context *ctx, int use_preedit);
+ void (*input_mode_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode);
+ int (*filter_event) (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event);
+ };
+
+ struct _Ecore_IMF_Context_Info
+ {
+ const char *id; /* ID */
+ const char *description; /* Human readable description */
+ const char *default_locales; /* Languages for which this context is the default, separated by : */
+ const char *canvas_type; /* The canvas type used by the input method. Eg.: evas */
+ int canvas_required; /* Whether the canvas usage is required for this input method */
+ };
+
+ EAPI int ecore_imf_init(void);
+ EAPI int ecore_imf_shutdown(void);
+
+ EAPI void ecore_imf_module_register(const Ecore_IMF_Context_Info *info, Ecore_IMF_Context *(*imf_module_create)(void), Ecore_IMF_Context *(*imf_module_exit)(void));
+
+ EAPI Eina_List *ecore_imf_context_available_ids_get(void);
+ EAPI Eina_List *ecore_imf_context_available_ids_by_canvas_type_get(const char *canvas_type);
+ EAPI const char *ecore_imf_context_default_id_get(void);
+ EAPI const char *ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type);
+ EAPI const Ecore_IMF_Context_Info *ecore_imf_context_info_by_id_get(const char *id);
+
+ EAPI Ecore_IMF_Context *ecore_imf_context_add(const char *id);
+ EAPI const Ecore_IMF_Context_Info *ecore_imf_context_info_get(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_del(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window);
+ EAPI void ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas);
+ EAPI void ecore_imf_context_show(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_hide(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos);
+ EAPI void ecore_imf_context_focus_in(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_focus_out(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_reset(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos);
+ EAPI void ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, int use_preedit);
+ EAPI void ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, int (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data);
+ EAPI void ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode);
+ EAPI Ecore_IMF_Input_Mode ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx);
+ EAPI int ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event);
+
+ /* plugin specific functions */
+ EAPI Ecore_IMF_Context *ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc);
+ EAPI void ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data);
+ EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx);
+ EAPI int ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
+ EAPI void ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx);
+ EAPI void ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str);
+ EAPI void ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars);
+
+ /* The following entry points must be exported by each input method module
+ */
+
+ /*
+ * int imf_module_init (const Ecore_IMF_Context_Info **info);
+ * void imf_module_exit (void);
+ * Ecore_IMF_Context *imf_module_create (void);
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_IMF
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+@EFL_ECORE_IMF_BUILD@ \
+@EVIL_CFLAGS@ \
+@EINA_CFLAGS@
+
+AM_CFLAGS = @WIN32_CFLAGS@
+
+lib_LTLIBRARIES = libecore_imf.la
+include_HEADERS = \
+Ecore_IMF.h
+
+libecore_imf_la_SOURCES = \
+ecore_imf.c \
+ecore_imf_context.c \
+ecore_imf_module.c
+
+libecore_imf_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@EINA_LIBS@ \
+@EVIL_LIBS@
+
+libecore_imf_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_imf_release_info@
+endif
+
+EXTRA_DIST = ecore_imf_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include <ecore_private.h>
+
+#include "Ecore_IMF.h"
+#include "ecore_imf_private.h"
+
+EAPI int ECORE_IMF_EVENT_PREEDIT_START = 0;
+EAPI int ECORE_IMF_EVENT_PREEDIT_END = 0;
+EAPI int ECORE_IMF_EVENT_PREEDIT_CHANGED = 0;
+EAPI int ECORE_IMF_EVENT_COMMIT = 0;
+EAPI int ECORE_IMF_EVENT_DELETE_SURROUNDING = 0;
+
+int _ecore_imf_log_dom = -1;
+static int _ecore_imf_init_count = 0;
+
+/**
+ * @defgroup Ecore_IMF_Lib_Group Ecore Input Method Library Functions
+ *
+ * Utility functions that set up and shut down the Ecore Input Method
+ * library.
+ */
+
+/**
+ * Initialises the Ecore_IMF library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_IMF_Lib_Group
+ */
+EAPI int
+ecore_imf_init(void)
+{
+ if (++_ecore_imf_init_count != 1)
+ return _ecore_imf_init_count;
+
+ if (!ecore_init())
+ return --_ecore_imf_init_count;
+ _ecore_imf_log_dom = eina_log_domain_register("EcoreIMF", ECORE_IMF_DEFAULT_LOG_COLOR);
+ if(_ecore_imf_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the Ecore IMF module.");
+ ecore_shutdown();
+ return --_ecore_imf_init_count;
+ }
+ ecore_imf_module_init();
+
+ ECORE_IMF_EVENT_PREEDIT_START = ecore_event_type_new();
+ ECORE_IMF_EVENT_PREEDIT_END = ecore_event_type_new();
+ ECORE_IMF_EVENT_PREEDIT_CHANGED = ecore_event_type_new();
+ ECORE_IMF_EVENT_COMMIT = ecore_event_type_new();
+ ECORE_IMF_EVENT_DELETE_SURROUNDING = ecore_event_type_new();
+
+ return _ecore_imf_init_count;
+}
+
+/**
+ * Shuts down the Ecore_IMF library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_IMF_Lib_Group
+ */
+EAPI int
+ecore_imf_shutdown(void)
+{
+ if (--_ecore_imf_init_count != 0)
+ return _ecore_imf_init_count;
+
+ ecore_shutdown();
+ ecore_imf_module_shutdown();
+ eina_log_domain_unregister(_ecore_imf_log_dom);
+ _ecore_imf_log_dom = -1;
+ return _ecore_imf_init_count;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+
+#include <Ecore.h>
+#include <ecore_private.h>
+
+#include "Ecore_IMF.h"
+#include "ecore_imf_private.h"
+
+/**
+ * @defgroup Ecore_IMF_Context_Group Ecore Input Method Context Functions
+ *
+ * Functions that operate on Ecore Input Method Context objects.
+ */
+
+/**
+ * Get the list of the available Input Method Context ids.
+ *
+ * Note that the caller is responsible for freeing the Eina_List
+ * when finished with it. There is no need to finish the list strings.
+ *
+ * @return Return an EIna_List of strings;
+ * on failure it returns NULL.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI Eina_List *
+ecore_imf_context_available_ids_get(void)
+{
+ return ecore_imf_module_context_ids_get();
+}
+
+EAPI Eina_List *
+ecore_imf_context_available_ids_by_canvas_type_get(const char *canvas_type)
+{
+ return ecore_imf_module_context_ids_by_canvas_type_get(canvas_type);
+}
+
+/*
+ * Match @locale against @against.
+ *
+ * 'en_US' against 'en_US' => 4
+ * 'en_US' against 'en' => 3
+ * 'en', 'en_UK' against 'en_US' => 2
+ * all locales, against '*' => 1
+ */
+static int
+_ecore_imf_context_match_locale(const char *locale, const char *against, int against_len)
+{
+ if (strcmp(against, "*") == 0)
+ return 1;
+
+ if (strcasecmp(locale, against) == 0)
+ return 4;
+
+ if (strncasecmp(locale, against, 2) == 0)
+ return (against_len == 2) ? 3 : 2;
+
+ return 0;
+}
+
+/**
+ * Get the id of the default Input Method Context.
+ * The id may to used to create a new instance of an Input Method
+ * Context object.
+ *
+ * @return Return a string containing the id of the default Input
+ * Method Context; on failure it returns NULL.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI const char *
+ecore_imf_context_default_id_get(void)
+{
+ return ecore_imf_context_default_id_by_canvas_type_get(NULL);
+}
+
+EAPI const char *
+ecore_imf_context_default_id_by_canvas_type_get(const char *canvas_type)
+{
+ const char *id;
+ Eina_List *modules;
+ Ecore_IMF_Module *module;
+ char *locale;
+ char *tmp;
+ int best_goodness = 0;
+
+ id = getenv("ECORE_IMF_MODULE");
+ if (id)
+ {
+ if (strcmp(id, "none") == 0) return NULL;
+ if (ecore_imf_module_get(id)) return id;
+ }
+
+ modules = ecore_imf_module_available_get();
+ if (!modules) return NULL;
+
+ locale = setlocale(LC_CTYPE, NULL);
+ if (!locale) return NULL;
+
+ locale = strdup(locale);
+
+ tmp = strchr(locale, '.');
+ if (tmp) *tmp = '\0';
+ tmp = strchr(locale, '@');
+ if (tmp) *tmp = '\0';
+
+ id = NULL;
+
+ EINA_LIST_FREE(modules, module)
+ {
+ if (canvas_type &&
+ strcmp(module->info->canvas_type, canvas_type) == 0)
+ continue;
+
+ const char *p = module->info->default_locales;
+ while (p)
+ {
+ const char *q = strchr(p, ':');
+ int goodness = _ecore_imf_context_match_locale(locale, p, q ? (size_t)(q - p) : strlen (p));
+
+ if (goodness > best_goodness)
+ {
+ id = module->info->id;
+ best_goodness = goodness;
+ }
+
+ p = q ? q + 1 : NULL;
+ }
+ }
+
+ free(locale);
+ return id;
+}
+
+/**
+ * Retrieve the info for the Input Method Context with @p id.
+ *
+ * @param id The Input Method Context id to query for.
+ * @return Return a #Ecore_IMF_Context_Info for the Input Method Context with @p id;
+ * on failure it returns NULL.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI const Ecore_IMF_Context_Info *
+ecore_imf_context_info_by_id_get(const char *id)
+{
+ Ecore_IMF_Module *module;
+
+ if (!id) return NULL;
+ module = ecore_imf_module_get(id);
+ if (!module) return NULL;
+ return module->info;
+}
+
+/**
+ * Create a new Input Method Context defined by the given id.
+ *
+ * @param id The Input Method Context id.
+ * @return A newly allocated Input Method Context;
+ * on failure it returns NULL.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI Ecore_IMF_Context *
+ecore_imf_context_add(const char *id)
+{
+ Ecore_IMF_Context *ctx;
+
+ if (!id) return NULL;
+ ctx = ecore_imf_module_context_create(id);
+ if (!ctx || !ctx->klass) return NULL;
+ if (ctx->klass->add) ctx->klass->add(ctx);
+ /* default use_preedit is 1, so let's make sure it's
+ * set on the immodule */
+ ecore_imf_context_use_preedit_set(ctx, 1);
+ /* default input_mode is ECORE_IMF_INPUT_MODE_FULL, so let's make sure it's
+ * set on the immodule */
+ ecore_imf_context_input_mode_set(ctx, ECORE_IMF_INPUT_MODE_FULL);
+ return ctx;
+}
+
+/**
+ * Retrieve the info for the given Input Method Context.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return Return a #Ecore_IMF_Context_Info for the given Input Method Context;
+ * on failure it returns NULL.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI const Ecore_IMF_Context_Info *
+ecore_imf_context_info_get(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_info_get");
+ return NULL;
+ }
+ return ctx->module->info;
+}
+
+/**
+ * Delete the given Input Method Context and free its memory.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_del(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_del");
+ return;
+ }
+ if (ctx->klass->del) ctx->klass->del(ctx);
+ ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE);
+ free(ctx);
+}
+
+/**
+ * Set the client window for the Input Method Context; this is the
+ * Ecore_X_Window when using X11, Ecore_Win32_Window when using Win32, etc.
+ * This window is used in order to correctly position status windows, and may
+ * also be used for purposes internal to the Input Method Context.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param window The client window. This may be NULL to indicate
+ * that the previous client window no longer exists.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_client_window_set");
+ return;
+ }
+ if (ctx->klass->client_window_set) ctx->klass->client_window_set(ctx, window);
+}
+
+/**
+ * Set the client canvas for the Input Method Context; this is the
+ * canvas in which the input appears.
+ * The canvas type can be determined by using the context canvas type.
+ * Actually only canvas with type "evas" (Evas *) is supported.
+ * This canvas may be used in order to correctly position status windows, and may
+ * also be used for purposes internal to the Input Method Context.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param canas The client canvas. This may be NULL to indicate
+ * that the previous client canvas no longer exists.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_client_window_set");
+ return;
+ }
+ if (ctx->klass->client_canvas_set) ctx->klass->client_canvas_set(ctx, canvas);
+}
+
+/**
+ * Ask the Input Method Context to show itself.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_show(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_show");
+ return;
+ }
+ if (ctx->klass->show) ctx->klass->show(ctx);
+}
+
+/**
+ * Ask the Input Method Context to hide itself.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_hide(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_hide");
+ return;
+ }
+ if (ctx->klass->hide) ctx->klass->hide(ctx);
+}
+
+/*
+ * Retrieve the current preedit string and cursor position
+ * for the Input Method Context.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param str Location to store the retrieved string. The
+ * string retrieved must be freed with free().
+ * @param cursor_pos Location to store position of cursor (in characters)
+ * within the preedit string.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char **str, int *cursor_pos)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_preedit_string_get");
+ return;
+ }
+ if (ctx->klass->preedit_string_get)
+ ctx->klass->preedit_string_get(ctx, str, cursor_pos);
+ else
+ {
+ if (str) *str = strdup("");
+ if (cursor_pos) *cursor_pos = 0;
+ }
+}
+
+/**
+ * Notify the Input Method Context that the widget to which its
+ * correspond has gained focus.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_focus_in(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_focus_in");
+ return;
+ }
+ if (ctx->klass->focus_in) ctx->klass->focus_in(ctx);
+}
+
+/**
+ * Notify the Input Method Context that the widget to which its
+ * correspond has lost focus.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_focus_out(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_focus_out");
+ return;
+ }
+ if (ctx->klass->focus_out) ctx->klass->focus_out(ctx);
+}
+
+/**
+ * Notify the Input Method Context that a change such as a
+ * change in cursor position has been made. This will typically
+ * cause the Input Method Context to clear the preedit state.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_reset(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_reset");
+ return;
+ }
+ if (ctx->klass->reset) ctx->klass->reset(ctx);
+}
+
+/**
+ * Notify the Input Method Context that a change in the cursor
+ * position has been made.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param cursor_pos New cursor position in characters.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_cursor_position_set");
+ return;
+ }
+ if (ctx->klass->cursor_position_set) ctx->klass->cursor_position_set(ctx, cursor_pos);
+}
+
+/**
+ * Set whether the IM context should use the preedit string
+ * to display feedback. If @use_preedit is 0 (default
+ * is 1), then the IM context may use some other method to display
+ * feedback, such as displaying it in a child of the root window.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param use_preedit Whether the IM context should use the preedit string.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, int use_preedit)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_use_preedit_set");
+ return;
+ }
+ if (ctx->klass->use_preedit_set) ctx->klass->use_preedit_set(ctx, use_preedit);
+}
+
+/**
+ * Set the callback to be used on get_surrounding request.
+ *
+ * This callback will be called when the Input Method Context
+ * module requests the surrounding context.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param func The callback to be called.
+ * @param data The data pointer to be passed to @p func
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, int (*func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos), const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_retrieve_surrounding_callback_set");
+ return;
+ }
+
+ ctx->retrieve_surrounding_func = func;
+ ctx->retrieve_surrounding_data = (void *) data;
+}
+
+/**
+ * Set the input mode used by the Ecore Input Context.
+ *
+ * The input mode can be one of the input modes defined in
+ * #Ecore_IMF_Input_Mode. The default input mode is
+ * ECORE_IMF_INPUT_MODE_FULL.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param input_mode The input mode to be used by @p ctx.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI void
+ecore_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_input_mode_set");
+ return;
+ }
+ if (ctx->klass->input_mode_set) ctx->klass->input_mode_set(ctx, input_mode);
+ ctx->input_mode = input_mode;
+}
+
+/**
+ * Get the input mode being used by the Ecore Input Context.
+ *
+ * See @ref ecore_imf_context_input_mode_set for more details.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return The input mode being used by @p ctx.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI Ecore_IMF_Input_Mode
+ecore_imf_context_input_mode_get(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_input_mode_set");
+ return 0;
+ }
+ return ctx->input_mode;
+}
+
+/**
+ * Allow an Ecore Input Context to internally handle an event.
+ * If this function returns 1, then no further processing
+ * should be done for this event.
+ *
+ * Input methods must be able to accept all types of events (simply
+ * returning 0 if the event was not handled), but there is no
+ * obligation of any events to be submitted to this function.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param type The type of event defined by #Ecore_IMF_Event_Type.
+ * @param event The event itself.
+ * @return 1 if the event was handled; otherwise 0.
+ * @ingroup Ecore_IMF_Context_Group
+ */
+EAPI int
+ecore_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_filter_event");
+ return 0;
+ }
+ if (ctx->klass->filter_event) return ctx->klass->filter_event(ctx, type, event);
+ return 0;
+}
+
+/**
+ * @defgroup Ecore_IMF_Context_Module_Group Ecore Input Method Context Module Functions
+ *
+ * Functions that should be used by Ecore Input Method Context modules.
+ */
+
+/**
+ * Creates a new Input Method Context with klass specified by @p ctxc.
+ *
+ * This method should be used by modules implementing the Input
+ * Method Context interface.
+ *
+ * @param ctxc An #Ecore_IMF_Context_Class.
+ * @return A new #Ecore_IMF_Context; on failure it returns NULL.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI Ecore_IMF_Context *
+ecore_imf_context_new(const Ecore_IMF_Context_Class *ctxc)
+{
+ Ecore_IMF_Context *ctx;
+
+ if (!ctxc) return NULL;
+ ctx = malloc(sizeof(Ecore_IMF_Context));
+ if (!ctx) return NULL;
+ ECORE_MAGIC_SET(ctx, ECORE_MAGIC_CONTEXT);
+ ctx->klass = ctxc;
+ ctx->data = NULL;
+ ctx->retrieve_surrounding_func = NULL;
+ ctx->retrieve_surrounding_data = NULL;
+ return ctx;
+}
+
+/**
+ * Set the Input Method Context specific data.
+ *
+ * Note that this method should be used by modules to set
+ * the Input Method Context specific data and it's not meant to
+ * be used by applications to store application specific data.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param data The Input Method Context specific data.
+ * @return A new #Ecore_IMF_Context; on failure it returns NULL.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI void
+ecore_imf_context_data_set(Ecore_IMF_Context *ctx, void *data)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_data_set");
+ return;
+ }
+ ctx->data = data;
+}
+
+/**
+ * Get the Input Method Context specific data.
+ *
+ * See @ref ecore_imf_context_data_set for more details.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @return The Input Method Context specific data.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI void *ecore_imf_context_data_get(Ecore_IMF_Context *ctx)
+{
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_data_get");
+ return NULL;
+ }
+ return ctx->data;
+}
+
+/**
+ * Retrieve context around insertion point.
+ *
+ * This function is implemented by calling the
+ * Ecore_IMF_Context::retrieve_surrounding_func (
+ * set using #ecore_imf_context_retrieve_surrounding_callback_set).
+ *
+ * There is no obligation for a widget to respond to the
+ * ::retrieve_surrounding_func, so input methods must be prepared
+ * to function without context.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param text Location to store a UTF-8 encoded string of text
+ * holding context around the insertion point.
+ * If the function returns 1, then you must free
+ * the result stored in this location with free().
+ * @param cursor_pos Location to store the position in characters of
+ * the insertion cursor within @text.
+ * @return 1 if surrounding text was provided; otherwise 0.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI int
+ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos)
+{
+ int result = 0;
+
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_surrounding_get");
+ return 0;
+ }
+
+ if (ctx->retrieve_surrounding_func)
+ {
+ result = ctx->retrieve_surrounding_func(ctx->retrieve_surrounding_data, ctx, text, cursor_pos);
+ if (!result)
+ {
+ if (text) *text = NULL;
+ if (cursor_pos) *cursor_pos = 0;
+ }
+ }
+ return result;
+}
+
+static void
+_ecore_imf_event_free_preedit(void *data __UNUSED__, void *event)
+{
+ free(event);
+}
+
+/**
+ * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI void
+ecore_imf_context_preedit_start_event_add(Ecore_IMF_Context *ctx)
+{
+ Ecore_IMF_Event_Commit *ev;
+
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_preedit_start_event_add");
+ return;
+ }
+
+ ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Start));
+ ev->ctx = ctx;
+ ecore_event_add(ECORE_IMF_EVENT_PREEDIT_START,
+ ev, _ecore_imf_event_free_preedit, NULL);
+}
+
+/**
+ * Adds ECORE_IMF_EVENT_PREEDIT_END to the event queue.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI void
+ecore_imf_context_preedit_end_event_add(Ecore_IMF_Context *ctx)
+{
+ Ecore_IMF_Event_Commit *ev;
+
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_preedit_end_event_add");
+ return;
+ }
+
+ ev = malloc(sizeof(Ecore_IMF_Event_Preedit_End));
+ ev->ctx = ctx;
+ ecore_event_add(ECORE_IMF_EVENT_PREEDIT_END,
+ ev, _ecore_imf_event_free_preedit, NULL);
+}
+
+/**
+ * Adds ECORE_IMF_EVENT_PREEDIT_CHANGED to the event queue.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI void
+ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx)
+{
+ Ecore_IMF_Event_Commit *ev;
+
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_preedit_changed_event_add");
+ return;
+ }
+
+ ev = malloc(sizeof(Ecore_IMF_Event_Preedit_Changed));
+ ev->ctx = ctx;
+ ecore_event_add(ECORE_IMF_EVENT_PREEDIT_CHANGED,
+ ev, _ecore_imf_event_free_preedit, NULL);
+}
+
+static void
+_ecore_imf_event_free_commit(void *data __UNUSED__, void *event)
+{
+ Ecore_IMF_Event_Commit *ev;
+
+ ev = event;
+ if (ev->str) free(ev->str);
+ free(ev);
+}
+
+/**
+ * Adds ECORE_IMF_EVENT_COMMIT to the event queue.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param str The committed string.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI void
+ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str)
+{
+ Ecore_IMF_Event_Commit *ev;
+
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_commit_event_add");
+ return;
+ }
+
+ ev = malloc(sizeof(Ecore_IMF_Event_Commit));
+ ev->ctx = ctx;
+ ev->str = str ? strdup(str) : NULL;
+ ecore_event_add(ECORE_IMF_EVENT_COMMIT,
+ ev, _ecore_imf_event_free_commit, NULL);
+
+}
+
+static void
+_ecore_imf_event_free_delete_surrounding(void *data __UNUSED__, void *event)
+{
+ free(event);
+}
+
+/**
+ * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue.
+ *
+ * @param ctx An #Ecore_IMF_Context.
+ * @param offset The start offset of surrounding to be deleted.
+ * @param n_chars The number of characters to be deleted.
+ * @ingroup Ecore_IMF_Context_Module_Group
+ */
+EAPI void
+ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars)
+{
+ Ecore_IMF_Event_Delete_Surrounding *ev;
+
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_context_delete_surrounding_event_add");
+ return;
+ }
+
+ ev = malloc(sizeof(Ecore_IMF_Event_Delete_Surrounding));
+ ev->ctx = ctx;
+ ev->offset = offset;
+ ev->n_chars = n_chars;
+ ecore_event_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
+ ev, _ecore_imf_event_free_delete_surrounding, NULL);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <Ecore.h>
+#include <ecore_private.h>
+
+#include "Ecore_IMF.h"
+#include "ecore_imf_private.h"
+
+static void _ecore_imf_module_free(Ecore_IMF_Module *module);
+static int _ecore_imf_modules_exists(const char *ctx_id);
+
+typedef struct _Ecore_IMF_Selector
+{
+ const char *toselect;
+ void *selected;
+} Ecore_IMF_Selector;
+
+static Eina_Hash *modules = NULL;
+static Eina_Array *module_list = NULL;
+
+void
+ecore_imf_module_init(void)
+{
+ char *homedir;
+
+ module_list = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/ecore/immodules", 0, NULL, NULL);
+ homedir = eina_module_environment_path_get("HOME", "/.ecore/immodules");
+ if (homedir)
+ {
+ module_list = eina_module_list_get(module_list, homedir, 0, NULL, NULL);
+ free(homedir);
+ }
+ eina_module_list_load(module_list);
+}
+
+void
+ecore_imf_module_shutdown(void)
+{
+ if (modules)
+ {
+ eina_hash_free(modules);
+ modules = NULL;
+ }
+ if (module_list)
+ {
+ eina_module_list_free(module_list);
+ modules = NULL;
+ }
+}
+
+static Eina_Bool
+_hash_module_available_get(const Eina_Hash *hash __UNUSED__, int *data, void *list)
+{
+ *(Eina_List**)list = eina_list_append(*(Eina_List**)list, data);
+ return EINA_TRUE;
+}
+
+Eina_List *
+ecore_imf_module_available_get(void)
+{
+ Eina_List *values = NULL;
+ Eina_Iterator *it = NULL;
+
+ if (!modules) return NULL;
+
+ it = eina_hash_iterator_data_new(modules);
+ if (!it)
+ return NULL;
+
+ eina_iterator_foreach(it, EINA_EACH(_hash_module_available_get), &values);
+ eina_iterator_free(it);
+
+ return values;
+}
+
+Ecore_IMF_Module *
+ecore_imf_module_get(const char *ctx_id)
+{
+ if (!modules) return NULL;
+ return eina_hash_find(modules, ctx_id);
+}
+
+Ecore_IMF_Context *
+ecore_imf_module_context_create(const char *ctx_id)
+{
+ Ecore_IMF_Module *module;
+ Ecore_IMF_Context *ctx = NULL;
+
+ if (!modules) return NULL;
+ module = eina_hash_find(modules, ctx_id);
+ if (module)
+ {
+ ctx = module->create();
+ if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT))
+ {
+ ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT,
+ "ecore_imf_module_context_create");
+ return NULL;
+ }
+ ctx->module = module;
+ }
+ return ctx;
+}
+
+static Eina_Bool
+_hash_ids_get(const Eina_Hash *hash __UNUSED__, const char *key, void *list)
+{
+ *(Eina_List**)list = eina_list_append(*(Eina_List**)list, key);
+ return EINA_TRUE;
+}
+
+Eina_List *
+ecore_imf_module_context_ids_get(void)
+{
+ Eina_List *l = NULL;
+ Eina_Iterator *it = NULL;
+
+ if (!modules) return NULL;
+
+ it = eina_hash_iterator_key_new(modules);
+ if (!it)
+ return NULL;
+
+ eina_iterator_foreach(it, EINA_EACH(_hash_ids_get), &l);
+ eina_iterator_free(it);
+
+ return l;
+}
+
+static Eina_Bool
+_hash_ids_by_canvas_type_get(const Eina_Hash *hash __UNUSED__, void *data, void *fdata)
+{
+ Ecore_IMF_Module *module = data;
+ Ecore_IMF_Selector *selector = fdata;
+
+ if (!strcmp(module->info->canvas_type, selector->toselect))
+ selector->selected = eina_list_append(selector->selected, (void *)module->info->id);
+
+ return EINA_TRUE;
+}
+
+Eina_List *
+ecore_imf_module_context_ids_by_canvas_type_get(const char *canvas_type)
+{
+ Ecore_IMF_Selector selector;
+ Eina_List *values = NULL;
+ Eina_Iterator *it = NULL;
+
+ if (!modules) return NULL;
+
+ if (!canvas_type)
+ return ecore_imf_module_context_ids_get();
+
+ it = eina_hash_iterator_data_new(modules);
+ if (!it)
+ return NULL;
+
+ selector.toselect = canvas_type;
+ selector.selected = values;
+ eina_iterator_foreach(it, EINA_EACH(_hash_ids_by_canvas_type_get), &selector);
+ eina_iterator_free(it);
+
+ return values;
+}
+
+EAPI void
+ecore_imf_module_register(const Ecore_IMF_Context_Info *info,
+ Ecore_IMF_Context *(*imf_module_create)(void),
+ Ecore_IMF_Context *(*imf_module_exit)(void))
+{
+ Ecore_IMF_Module *module;
+
+ if (_ecore_imf_modules_exists(info->id)) return;
+
+ if (!modules)
+ modules = eina_hash_string_superfast_new(EINA_FREE_CB(_ecore_imf_module_free));
+
+ module = malloc(sizeof(Ecore_IMF_Module));
+ module->info = info;
+ /* cache imf_module_create as it may be used several times */
+ module->create = imf_module_create;
+ module->exit = imf_module_exit;
+
+ eina_hash_add(modules, info->id, module);
+}
+
+static void
+_ecore_imf_module_free(Ecore_IMF_Module *module)
+{
+ if (module->exit) module->exit();
+ free(module);
+}
+
+static int
+_ecore_imf_modules_exists(const char *ctx_id)
+{
+ if (!modules) return 0;
+ if (!ctx_id) return 0;
+
+ if (eina_hash_find(modules, ctx_id))
+ return 1;
+
+ return 0;
+}
--- /dev/null
+#ifndef _ECORE_IMF_PRIVATE_H
+#define _ECORE_IMF_PRIVATE_H
+
+#define ECORE_MAGIC_CONTEXT 0x56c1b39a
+
+#ifdef ECORE_IMF_DEFAULT_LOG_COLOR
+#undef ECORE_IMF_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_IMF_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+extern int _ecore_imf_log_dom;
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_imf_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_imf_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_imf_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_imf_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_imf_log_dom, __VA_ARGS__)
+
+typedef struct _Ecore_IMF_Module Ecore_IMF_Module;
+
+struct _Ecore_IMF_Context
+{
+ ECORE_MAGIC;
+ const Ecore_IMF_Module *module;
+ const Ecore_IMF_Context_Class *klass;
+ void *data;
+ int input_mode;
+ int (*retrieve_surrounding_func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
+ void *retrieve_surrounding_data;
+};
+
+struct _Ecore_IMF_Module
+{
+ const Ecore_IMF_Context_Info *info;
+ Ecore_IMF_Context *(*create)(void);
+ Ecore_IMF_Context *(*exit)(void);
+};
+
+void ecore_imf_module_init(void);
+void ecore_imf_module_shutdown(void);
+Eina_List *ecore_imf_module_available_get(void);
+Ecore_IMF_Module *ecore_imf_module_get(const char *ctx_id);
+Ecore_IMF_Context *ecore_imf_module_context_create(const char *ctx_id);
+Eina_List *ecore_imf_module_context_ids_get(void);
+Eina_List *ecore_imf_module_context_ids_by_canvas_type_get(const char *canvas_type);
+
+#endif
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef _ECORE_IMF_EVAS_H
+#define _ECORE_IMF_EVAS_H
+
+#include <Ecore_IMF.h>
+#include <Evas.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_IMF_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_EVAS_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ EAPI void ecore_imf_evas_event_mouse_in_wrap(Evas_Event_Mouse_In *evas_event, Ecore_IMF_Event_Mouse_In *imf_event);
+ EAPI void ecore_imf_evas_event_mouse_out_wrap(Evas_Event_Mouse_Out *evas_event, Ecore_IMF_Event_Mouse_Out *imf_event);
+ EAPI void ecore_imf_evas_event_mouse_move_wrap(Evas_Event_Mouse_Move *evas_event, Ecore_IMF_Event_Mouse_Move *imf_event);
+ EAPI void ecore_imf_evas_event_mouse_down_wrap(Evas_Event_Mouse_Down *evas_event, Ecore_IMF_Event_Mouse_Down *imf_event);
+ EAPI void ecore_imf_evas_event_mouse_up_wrap(Evas_Event_Mouse_Up *evas_event, Ecore_IMF_Event_Mouse_Up *imf_event);
+ EAPI void ecore_imf_evas_event_mouse_wheel_wrap(Evas_Event_Mouse_Wheel *evas_event, Ecore_IMF_Event_Mouse_Wheel *imf_event);
+ EAPI void ecore_imf_evas_event_key_down_wrap(Evas_Event_Key_Down *evas_event, Ecore_IMF_Event_Key_Down *imf_event);
+ EAPI void ecore_imf_evas_event_key_up_wrap(Evas_Event_Key_Up *evas_event, Ecore_IMF_Event_Key_Up *imf_event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_IMF_EVAS
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_imf \
+@EFL_ECORE_IMF_BUILD@ \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@
+
+lib_LTLIBRARIES = libecore_imf_evas.la
+include_HEADERS = \
+Ecore_IMF_Evas.h
+
+libecore_imf_evas_la_SOURCES = \
+ecore_imf_evas.c
+
+libecore_imf_evas_la_LIBADD = \
+$(top_builddir)/src/lib/ecore_imf/libecore_imf.la \
+@EVAS_LIBS@ \
+@EINA_LIBS@
+
+libecore_imf_evas_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_imf_evas_release_info@
+endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore_IMF_Evas.h"
+
+/**
+ * @defgroup Ecore_IMF_Evas_Group Ecore Input Method Context Evas Helper Functions
+ *
+ * Helper functions to make it easy to use Evas with Ecore_IMF.
+ */
+
+static const char *_ecore_imf_evas_event_empty = "";
+
+/* Converts the Evas modifiers to Ecore_IMF keyboard modifiers */
+static void
+_ecore_imf_evas_event_modifiers_wrap(Evas_Modifier *evas_modifiers,
+ Ecore_IMF_Keyboard_Modifiers *imf_keyboard_modifiers)
+{
+ if (!evas_modifiers || !imf_keyboard_modifiers)
+ return;
+
+ *imf_keyboard_modifiers = ECORE_IMF_KEYBOARD_MODIFIER_NONE;
+ if (evas_key_modifier_is_set(evas_modifiers, "Control"))
+ *imf_keyboard_modifiers |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
+ if (evas_key_modifier_is_set(evas_modifiers, "Alt"))
+ *imf_keyboard_modifiers |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
+ if (evas_key_modifier_is_set(evas_modifiers, "Shift"))
+ *imf_keyboard_modifiers |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;
+ if (evas_key_modifier_is_set(evas_modifiers, "Super") || evas_key_modifier_is_set(evas_modifiers, "Hyper"))
+ *imf_keyboard_modifiers |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
+}
+
+/* Converts the Evas locks to Ecore_IMF keyboard locks */
+static void
+_ecore_imf_evas_event_locks_wrap(Evas_Lock *evas_locks,
+ Ecore_IMF_Keyboard_Locks *imf_keyboard_locks)
+{
+ if (!evas_locks || !imf_keyboard_locks)
+ return;
+
+ *imf_keyboard_locks = ECORE_IMF_KEYBOARD_LOCK_NONE;
+ if (evas_key_lock_is_set(evas_locks, "Num_Lock"))
+ *imf_keyboard_locks |= ECORE_IMF_KEYBOARD_LOCK_NUM;
+ if (evas_key_lock_is_set(evas_locks, "Caps_Lock"))
+ *imf_keyboard_locks |= ECORE_IMF_KEYBOARD_LOCK_CAPS;
+ if (evas_key_lock_is_set(evas_locks, "Scroll_Lock"))
+ *imf_keyboard_locks |= ECORE_IMF_KEYBOARD_LOCK_SCROLL;
+}
+
+/* Converts the Evas mouse flags to Ecore_IMF mouse flags */
+static void
+_ecore_imf_evas_event_mouse_flags_wrap(Evas_Button_Flags evas_flags,
+ Ecore_IMF_Mouse_Flags *imf_flags)
+{
+ if (!imf_flags)
+ return;
+
+ *imf_flags = ECORE_IMF_MOUSE_NONE;
+ if (evas_flags & EVAS_BUTTON_DOUBLE_CLICK)
+ *imf_flags |= ECORE_IMF_MOUSE_DOUBLE_CLICK;
+ if (evas_flags & EVAS_BUTTON_TRIPLE_CLICK)
+ *imf_flags |= ECORE_IMF_MOUSE_TRIPLE_CLICK;
+}
+
+/**
+ * Converts a "mouse_in" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_mouse_in_wrap(Evas_Event_Mouse_In *evas_event,
+ Ecore_IMF_Event_Mouse_In *imf_event)
+{
+ if (!evas_event || !imf_event)
+ return;
+
+ imf_event->buttons = evas_event->buttons;
+ imf_event->output.x = evas_event->output.x;
+ imf_event->output.y = evas_event->output.y;
+ imf_event->canvas.x = evas_event->canvas.x;
+ imf_event->canvas.y = evas_event->canvas.y;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+}
+
+/**
+ * Converts a "mouse_out" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_mouse_out_wrap(Evas_Event_Mouse_Out *evas_event,
+ Ecore_IMF_Event_Mouse_Out *imf_event)
+{
+ if (!evas_event || !imf_event)
+ return;
+
+ imf_event->buttons = evas_event->buttons;
+ imf_event->output.x = evas_event->output.x;
+ imf_event->output.y = evas_event->output.y;
+ imf_event->canvas.x = evas_event->canvas.x;
+ imf_event->canvas.y = evas_event->canvas.y;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+}
+
+/**
+ * Converts a "mouse_move" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_mouse_move_wrap(Evas_Event_Mouse_Move *evas_event,
+ Ecore_IMF_Event_Mouse_Move *imf_event)
+{
+ if (!evas_event || !imf_event)
+ return;
+
+ imf_event->buttons = evas_event->buttons;
+ imf_event->cur.output.x = evas_event->cur.output.x;
+ imf_event->cur.output.y = evas_event->cur.output.y;
+ imf_event->prev.output.x = evas_event->prev.output.x;
+ imf_event->prev.output.y = evas_event->prev.output.y;
+ imf_event->cur.canvas.x = evas_event->cur.canvas.x;
+ imf_event->cur.canvas.y = evas_event->cur.canvas.y;
+ imf_event->prev.canvas.x = evas_event->prev.canvas.x;
+ imf_event->prev.canvas.y = evas_event->prev.canvas.y;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+}
+
+/**
+ * Converts a "mouse_down" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_mouse_down_wrap(Evas_Event_Mouse_Down *evas_event,
+ Ecore_IMF_Event_Mouse_Down *imf_event)
+{
+ if (!evas_event || !imf_event)
+ return;
+
+ imf_event->button = evas_event->button;
+ imf_event->output.x = evas_event->output.x;
+ imf_event->output.y = evas_event->output.y;
+ imf_event->canvas.x = evas_event->canvas.x;
+ imf_event->canvas.y = evas_event->canvas.y;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+ _ecore_imf_evas_event_mouse_flags_wrap(evas_event->flags, &imf_event->flags);
+}
+
+/**
+ * Converts a "mouse_up" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_mouse_up_wrap(Evas_Event_Mouse_Up *evas_event,
+ Ecore_IMF_Event_Mouse_Up *imf_event)
+{
+ if (!evas_event || !imf_event)
+ return;
+
+ imf_event->button = evas_event->button;
+ imf_event->output.x = evas_event->output.x;
+ imf_event->output.y = evas_event->output.y;
+ imf_event->canvas.x = evas_event->canvas.x;
+ imf_event->canvas.y = evas_event->canvas.y;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+ _ecore_imf_evas_event_mouse_flags_wrap(evas_event->flags, &imf_event->flags);
+}
+
+/**
+ * Converts a "mouse_wheel" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_mouse_wheel_wrap(Evas_Event_Mouse_Wheel *evas_event,
+ Ecore_IMF_Event_Mouse_Wheel *imf_event)
+{
+ if (!evas_event || !imf_event)
+ return;
+
+ imf_event->direction = evas_event->direction;
+ imf_event->z = evas_event->z;
+ imf_event->output.x = evas_event->output.x;
+ imf_event->output.y = evas_event->output.y;
+ imf_event->canvas.x = evas_event->canvas.x;
+ imf_event->canvas.y = evas_event->canvas.y;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+ imf_event->timestamp = evas_event->timestamp;
+}
+
+/**
+ * Converts a "key_down" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_key_down_wrap(Evas_Event_Key_Down *evas_event,
+ Ecore_IMF_Event_Key_Down *imf_event)
+{
+ if (!evas_event || !imf_event)
+ return;
+
+ imf_event->keyname = evas_event->keyname ? evas_event->keyname : _ecore_imf_evas_event_empty;
+ imf_event->key = evas_event->key ? evas_event->key : _ecore_imf_evas_event_empty;
+ imf_event->string = evas_event->string ? evas_event->string : _ecore_imf_evas_event_empty;
+ imf_event->compose = evas_event->compose ? evas_event->compose : _ecore_imf_evas_event_empty;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+}
+
+/**
+ * Converts a "key_up" event from Evas to the corresponding event of Ecore_IMF.
+ *
+ * @param evas_event The received Evas event.
+ * @param imf_event The location to store the converted Ecore_IMF event.
+ * @ingroup Ecore_IMF_Evas_Group
+ */
+EAPI void
+ecore_imf_evas_event_key_up_wrap(Evas_Event_Key_Up *evas_event,
+ Ecore_IMF_Event_Key_Up *imf_event)
+{
+ imf_event->keyname = evas_event->keyname ? evas_event->keyname : _ecore_imf_evas_event_empty;
+ imf_event->key = evas_event->key ? evas_event->key : _ecore_imf_evas_event_empty;
+ imf_event->string = evas_event->string ? evas_event->string : _ecore_imf_evas_event_empty;
+ imf_event->compose = evas_event->compose ? evas_event->compose : _ecore_imf_evas_event_empty;
+ imf_event->timestamp = evas_event->timestamp;
+ _ecore_imf_evas_event_modifiers_wrap(evas_event->modifiers, &imf_event->modifiers);
+ _ecore_imf_evas_event_locks_wrap(evas_event->locks, &imf_event->locks);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef _ECORE_INPUT_H
+#define _ECORE_INPUT_H
+
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_INPUT_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_INPUT_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EAPI extern int ECORE_EVENT_KEY_DOWN;
+EAPI extern int ECORE_EVENT_KEY_UP;
+EAPI extern int ECORE_EVENT_MOUSE_BUTTON_DOWN;
+EAPI extern int ECORE_EVENT_MOUSE_BUTTON_UP;
+EAPI extern int ECORE_EVENT_MOUSE_MOVE;
+EAPI extern int ECORE_EVENT_MOUSE_WHEEL;
+EAPI extern int ECORE_EVENT_MOUSE_IN;
+EAPI extern int ECORE_EVENT_MOUSE_OUT;
+
+#define ECORE_EVENT_MODIFIER_SHIFT 0x0001
+#define ECORE_EVENT_MODIFIER_CTRL 0x0002
+#define ECORE_EVENT_MODIFIER_ALT 0x0004
+#define ECORE_EVENT_MODIFIER_WIN 0x0008
+#define ECORE_EVENT_MODIFIER_SCROLL 0x0010
+#define ECORE_EVENT_MODIFIER_NUM 0x0020
+#define ECORE_EVENT_MODIFIER_CAPS 0x0040
+#define ECORE_EVENT_LOCK_SCROLL 0x0080
+#define ECORE_EVENT_LOCK_NUM 0x0100
+#define ECORE_EVENT_LOCK_CAPS 0x0200
+
+typedef uintptr_t Ecore_Window;
+
+typedef struct _Ecore_Event_Key Ecore_Event_Key;
+struct _Ecore_Event_Key
+{
+ const char *keyname;
+ const char *key;
+ const char *string;
+ const char *compose;
+ Ecore_Window window;
+ Ecore_Window root_window;
+ Ecore_Window event_window;
+
+ unsigned int timestamp;
+ unsigned int modifiers;
+
+ int same_screen;
+};
+
+typedef struct _Ecore_Event_Mouse_Button Ecore_Event_Mouse_Button;
+struct _Ecore_Event_Mouse_Button
+{
+ Ecore_Window window;
+ Ecore_Window root_window;
+ Ecore_Window event_window;
+
+ unsigned int timestamp;
+ unsigned int modifiers;
+ unsigned int buttons;
+ unsigned int double_click;
+ unsigned int triple_click;
+ int same_screen;
+
+ int x;
+ int y;
+ struct
+ {
+ int x;
+ int y;
+ } root;
+
+ struct
+ {
+ int device; /* 0 if normal mouse, 1+ for other mouse-devices (eg multi-touch - other fingers) */
+ double radius, radius_x, radius_y; /* radius of press point - radius_x and y if its an ellipse (radius is the average of the 2) */
+ double pressure; /* pressure - 1.0 == normal, > 1.0 == more, 0.0 == none */
+ double angle; /* angle relative to perpendicular (0.0 == perpendicular), in degrees */
+ double x, y; /* same as x, y root.x, root.y, but with sub-pixel precision, if available */
+ struct
+ {
+ double x, y;
+ } root;
+ } multi;
+};
+
+typedef struct _Ecore_Event_Mouse_Wheel Ecore_Event_Mouse_Wheel;
+struct _Ecore_Event_Mouse_Wheel
+{
+ Ecore_Window window;
+ Ecore_Window root_window;
+ Ecore_Window event_window;
+
+ unsigned int timestamp;
+ unsigned int modifiers;
+
+ int same_screen;
+ int direction;
+ int z;
+
+ int x;
+ int y;
+ struct
+ {
+ int x;
+ int y;
+ } root;
+};
+
+typedef struct _Ecore_Event_Mouse_Move Ecore_Event_Mouse_Move;
+struct _Ecore_Event_Mouse_Move
+{
+ Ecore_Window window;
+ Ecore_Window root_window;
+ Ecore_Window event_window;
+
+ unsigned int timestamp;
+ unsigned int modifiers;
+
+ int same_screen;
+
+ int x;
+ int y;
+ struct
+ {
+ int x;
+ int y;
+ } root;
+
+ struct
+ {
+ int device; /* 0 if normal mouse, 1+ for other mouse-devices (eg multi-touch - other fingers) */
+ double radius, radius_x, radius_y; /* radius of press point - radius_x and y if its an ellipse (radius is the average of the 2) */
+ double pressure; /* pressure - 1.0 == normal, > 1.0 == more, 0.0 == none */
+ double angle; /* angle relative to perpendicular (0.0 == perpendicular), in degrees */
+ double x, y; /* same as x, y root.x, root.y, but with sub-pixel precision, if available */
+ struct
+ {
+ double x, y;
+ } root;
+ } multi;
+};
+
+typedef struct _Ecore_Event_Mouse_IO Ecore_Event_Mouse_IO;
+struct _Ecore_Event_Mouse_IO
+{
+ Ecore_Window window;
+ Ecore_Window event_window;
+
+ unsigned int timestamp;
+ unsigned int modifiers;
+
+ int x;
+ int y;
+};
+
+enum _Ecore_Event_Modifier
+{
+ ECORE_NONE,
+ ECORE_SHIFT,
+ ECORE_CTRL,
+ ECORE_ALT,
+ ECORE_WIN,
+ ECORE_SCROLL,
+ ECORE_CAPS,
+ ECORE_LAST
+};
+
+enum _Ecore_Event_Press
+{
+ ECORE_DOWN,
+ ECORE_UP
+};
+
+enum _Ecore_Event_IO
+{
+ ECORE_IN,
+ ECORE_OUT
+};
+
+typedef enum _Ecore_Event_IO Ecore_Event_IO;
+typedef enum _Ecore_Event_Press Ecore_Event_Press;
+typedef enum _Ecore_Event_Modifier Ecore_Event_Modifier;
+
+typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers;
+struct _Ecore_Event_Modifiers
+{
+ unsigned int size;
+ unsigned int array[ECORE_LAST];
+};
+
+EAPI int ecore_event_init(void);
+EAPI int ecore_event_shutdown(void);
+
+EAPI unsigned int ecore_event_modifier_mask(Ecore_Event_Modifier modifier);
+EAPI Ecore_Event_Modifier ecore_event_update_modifier(const char *key, Ecore_Event_Modifiers *modifiers, int inc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore \
+@EFL_ECORE_INPUT_BUILD@ \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_ECORE_INPUT
+
+lib_LTLIBRARIES = libecore_input.la
+include_HEADERS = Ecore_Input.h
+
+libecore_input_la_SOURCES = \
+ecore_input.c
+
+libecore_input_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@EINA_LIBS@ \
+@EVIL_LIBS@
+
+libecore_input_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_input_release_info@
+
+endif
+
+EXTRA_DIST = ecore_input_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#include "Ecore_Input.h"
+#include "ecore_input_private.h"
+
+
+int _ecore_input_log_dom = -1;
+
+EAPI int ECORE_EVENT_KEY_DOWN = 0;
+EAPI int ECORE_EVENT_KEY_UP = 0;
+EAPI int ECORE_EVENT_MOUSE_BUTTON_DOWN = 0;
+EAPI int ECORE_EVENT_MOUSE_BUTTON_UP = 0;
+EAPI int ECORE_EVENT_MOUSE_MOVE = 0;
+EAPI int ECORE_EVENT_MOUSE_WHEEL = 0;
+EAPI int ECORE_EVENT_MOUSE_IN = 0;
+EAPI int ECORE_EVENT_MOUSE_OUT = 0;
+
+static int _ecore_event_init_count = 0;
+
+EAPI int
+ecore_event_init(void)
+{
+ if (++_ecore_event_init_count != 1)
+ return _ecore_event_init_count;
+
+ _ecore_input_log_dom = eina_log_domain_register("EcoreInput", ECORE_INPUT_DEFAULT_LOG_COLOR);
+ if(_ecore_input_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the ecore input module.");
+ return --_ecore_event_init_count;
+ }
+
+ ECORE_EVENT_KEY_DOWN = ecore_event_type_new();
+ ECORE_EVENT_KEY_UP = ecore_event_type_new();
+ ECORE_EVENT_MOUSE_BUTTON_DOWN = ecore_event_type_new();
+ ECORE_EVENT_MOUSE_BUTTON_UP = ecore_event_type_new();
+ ECORE_EVENT_MOUSE_MOVE = ecore_event_type_new();
+ ECORE_EVENT_MOUSE_WHEEL = ecore_event_type_new();
+ ECORE_EVENT_MOUSE_IN = ecore_event_type_new();
+ ECORE_EVENT_MOUSE_OUT = ecore_event_type_new();
+
+ return _ecore_event_init_count;
+}
+
+EAPI int
+ecore_event_shutdown(void)
+{
+ if (--_ecore_event_init_count != 0)
+ return _ecore_event_init_count;
+
+ ECORE_EVENT_KEY_DOWN = 0;
+ ECORE_EVENT_KEY_UP = 0;
+ ECORE_EVENT_MOUSE_BUTTON_DOWN = 0;
+ ECORE_EVENT_MOUSE_BUTTON_UP = 0;
+ ECORE_EVENT_MOUSE_MOVE = 0;
+ ECORE_EVENT_MOUSE_WHEEL = 0;
+ ECORE_EVENT_MOUSE_IN = 0;
+ ECORE_EVENT_MOUSE_OUT = 0;
+ eina_log_domain_unregister(_ecore_input_log_dom);
+ _ecore_input_log_dom = -1;
+ return _ecore_event_init_count;
+}
+
+typedef struct _Ecore_Event_Modifier_Match Ecore_Event_Modifier_Match;
+struct _Ecore_Event_Modifier_Match
+{
+ const char *key;
+ Ecore_Event_Modifier modifier;
+ unsigned int event_modifier;
+};
+
+static const Ecore_Event_Modifier_Match matchs[] = {
+ { "Shift_L", ECORE_SHIFT, ECORE_EVENT_MODIFIER_SHIFT },
+ { "Shift_R", ECORE_SHIFT, ECORE_EVENT_MODIFIER_SHIFT },
+ { "Alt_L", ECORE_ALT, ECORE_EVENT_MODIFIER_ALT },
+ { "Alt_R", ECORE_ALT, ECORE_EVENT_MODIFIER_ALT },
+ { "Control_L", ECORE_CTRL, ECORE_EVENT_MODIFIER_CTRL },
+ { "Control_R", ECORE_CTRL, ECORE_EVENT_MODIFIER_CTRL },
+ { "Caps_Lock", ECORE_CAPS, ECORE_EVENT_MODIFIER_CAPS },
+ { "Super_L", ECORE_WIN, ECORE_EVENT_MODIFIER_WIN },
+ { "Super_R", ECORE_WIN, ECORE_EVENT_MODIFIER_WIN },
+ { "Scroll_Lock", ECORE_SCROLL, ECORE_EVENT_MODIFIER_SCROLL }
+};
+
+EAPI unsigned int
+ecore_event_modifier_mask(Ecore_Event_Modifier modifier)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof (matchs) / sizeof (Ecore_Event_Modifier_Match); i++)
+ if (matchs[i].modifier == modifier)
+ return matchs[i].event_modifier;
+
+ return 0;
+}
+
+EAPI Ecore_Event_Modifier
+ecore_event_update_modifier(const char *key, Ecore_Event_Modifiers *modifiers, int inc)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof (matchs) / sizeof (Ecore_Event_Modifier_Match); i++)
+ if (strcmp(matchs[i].key, key) == 0)
+ {
+ if (modifiers && matchs[i].modifier < modifiers->size)
+ modifiers->array[matchs[i].modifier] += inc;
+ return matchs[i].modifier;
+ }
+
+ return ECORE_NONE;
+}
--- /dev/null
+#ifndef _ECORE_INPUT_PRIVATE_H
+#define _ECORE_INPUT_PRIVATE_H
+
+extern int _ecore_input_log_dom;
+
+#ifdef ECORE_INPUT_DEFAULT_LOG_COLOR
+# undef ECORE_INPUT_DEFAULT_LOG_COLOR
+#endif
+
+#define ECORE_INPUT_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_input_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_input_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_input_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_input_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_input_log_dom, __VA_ARGS__)
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef _ECORE_INPUT_EVAS_H
+#define _ECORE_INPUT_EVAS_H
+
+#include <Evas.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_INPUT_EVAS_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_INPUT_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*Ecore_Event_Mouse_Move_Cb)(void *window, int x, int y, unsigned int timestamp);
+
+EAPI int ecore_event_evas_init(void);
+EAPI int ecore_event_evas_shutdown(void);
+
+EAPI int ecore_event_evas_key_down(void *data, int type, void *event);
+EAPI int ecore_event_evas_key_up(void *data, int type, void *event);
+EAPI int ecore_event_evas_mouse_button_up(void *data, int type, void *event);
+EAPI int ecore_event_evas_mouse_button_down(void *data, int type, void *event);
+EAPI int ecore_event_evas_mouse_wheel(void *data, int type, void *event);
+EAPI int ecore_event_evas_mouse_move(void *data, int type, void *event);
+EAPI int ecore_event_evas_mouse_in(void *data, int type, void *event);
+EAPI int ecore_event_evas_mouse_out(void *data, int type, void *event);
+
+EAPI void ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, Ecore_Event_Mouse_Move_Cb move_mouse);
+EAPI void ecore_event_window_unregister(Ecore_Window id);
+EAPI void* ecore_event_window_match(Ecore_Window id);
+EAPI void ecore_event_window_ignore_events(Ecore_Window id, int ignore_event);
+
+EAPI void ecore_event_evas_modifier_lock_update(Evas *e, unsigned int modifiers);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore_input \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore \
+@EFL_ECORE_INPUT_EVAS_BUILD@ \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_ECORE_INPUT_EVAS
+
+lib_LTLIBRARIES = libecore_input_evas.la
+include_HEADERS = Ecore_Input_Evas.h
+
+libecore_input_evas_la_SOURCES = \
+ecore_input_evas.c
+
+libecore_input_evas_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+@EVAS_LIBS@ \
+@EINA_LIBS@ \
+@EVIL_LIBS@
+
+libecore_input_evas_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_input_evas_release_info@
+
+endif
+
+EXTRA_DIST = ecore_input_evas_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "Ecore_Input.h"
+
+#include "Ecore_Input_Evas.h"
+#include "ecore_input_evas_private.h"
+
+int _ecore_input_evas_log_dom = -1;
+
+typedef struct _Ecore_Input_Window Ecore_Input_Window;
+struct _Ecore_Input_Window
+{
+ Evas *evas;
+ void *window;
+ Ecore_Event_Mouse_Move_Cb move_mouse;
+ int ignore_event;
+};
+
+static int _ecore_event_evas_init_count = 0;
+static Ecore_Event_Handler *ecore_event_evas_handlers[8];
+static Eina_Hash *_window_hash = NULL;
+
+EAPI void
+ecore_event_evas_modifier_lock_update(Evas *e, unsigned int modifiers)
+{
+ if (modifiers & ECORE_EVENT_MODIFIER_SHIFT)
+ evas_key_modifier_on(e, "Shift");
+ else evas_key_modifier_off(e, "Shift");
+
+ if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
+ evas_key_modifier_on(e, "Control");
+ else evas_key_modifier_off(e, "Control");
+
+ if (modifiers & ECORE_EVENT_MODIFIER_ALT)
+ evas_key_modifier_on(e, "Alt");
+ else evas_key_modifier_off(e, "Alt");
+
+ if (modifiers & ECORE_EVENT_MODIFIER_WIN)
+ {
+ evas_key_modifier_on(e, "Super");
+ evas_key_modifier_on(e, "Hyper");
+ }
+ else
+ {
+ evas_key_modifier_off(e, "Super");
+ evas_key_modifier_off(e, "Hyper");
+ }
+
+ if (modifiers & ECORE_EVENT_LOCK_SCROLL)
+ evas_key_lock_on(e, "Scroll_Lock");
+ else evas_key_lock_off(e, "Scroll_Lock");
+
+ if (modifiers & ECORE_EVENT_LOCK_NUM)
+ evas_key_lock_on(e, "Num_Lock");
+ else evas_key_lock_off(e, "Num_Lock");
+
+ if (modifiers & ECORE_EVENT_LOCK_CAPS)
+ evas_key_lock_on(e, "Caps_Lock");
+ else evas_key_lock_off(e, "Caps_Lock");
+}
+
+EAPI void
+ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, Ecore_Event_Mouse_Move_Cb move_mouse)
+{
+ Ecore_Input_Window *w;
+
+ w = calloc(1, sizeof(Ecore_Input_Window));
+ if (!w) return;
+
+ w->evas = evas;
+ w->window = window;
+ w->move_mouse = move_mouse;
+ w->ignore_event = 0;
+
+ eina_hash_add(_window_hash, &id, w);
+
+ evas_key_modifier_add(evas, "Shift");
+ evas_key_modifier_add(evas, "Control");
+ evas_key_modifier_add(evas, "Alt");
+ evas_key_modifier_add(evas, "Meta");
+ evas_key_modifier_add(evas, "Hyper");
+ evas_key_modifier_add(evas, "Super");
+ evas_key_lock_add(evas, "Caps_Lock");
+ evas_key_lock_add(evas, "Num_Lock");
+ evas_key_lock_add(evas, "Scroll_Lock");
+}
+
+EAPI void
+ecore_event_window_unregister(Ecore_Window id)
+{
+ eina_hash_del(_window_hash, &id, NULL);
+}
+
+EAPI void *
+ecore_event_window_match(Ecore_Window id)
+{
+ Ecore_Input_Window *lookup;
+
+ lookup = eina_hash_find(_window_hash, &id);
+ if (lookup) return lookup->window;
+ return NULL;
+}
+
+EAPI void
+ecore_event_window_ignore_events(Ecore_Window id, int ignore_event)
+{
+ Ecore_Input_Window *lookup;
+
+ lookup = eina_hash_find(_window_hash, &id);
+ if (!lookup) return;
+ lookup->ignore_event = ignore_event;
+}
+
+static Ecore_Input_Window*
+_ecore_event_window_match(Ecore_Window id)
+{
+ Ecore_Input_Window *lookup;
+
+ lookup = eina_hash_find(_window_hash, &id);
+ if (!lookup) return NULL;
+ if (lookup->ignore_event) return NULL; /* Pass on event. */
+ return lookup;
+}
+
+static int
+_ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press)
+{
+ Ecore_Input_Window *lookup;
+
+ lookup = _ecore_event_window_match(e->window);
+ if (!lookup) return 1;
+ ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
+ if (press == ECORE_DOWN)
+ evas_event_feed_key_down(lookup->evas, e->keyname, e->key, e->string, e->compose, e->timestamp, NULL);
+ else
+ evas_event_feed_key_up(lookup->evas, e->keyname, e->key, e->string, e->compose, e->timestamp, NULL);
+ return 1;
+}
+
+static int
+_ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press)
+{
+ Ecore_Input_Window *lookup;
+ Evas_Button_Flags flags = EVAS_BUTTON_NONE;
+
+ lookup = _ecore_event_window_match(e->window);
+ if (!lookup) return 1;
+ if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
+ if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
+ if (e->multi.device == 0)
+ {
+ ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
+ if (press == ECORE_DOWN)
+ evas_event_feed_mouse_down(lookup->evas, e->buttons, flags, e->timestamp, NULL);
+ else
+ evas_event_feed_mouse_up(lookup->evas, e->buttons, flags, e->timestamp, NULL);
+ }
+ else
+ {
+ if (press == ECORE_DOWN)
+ evas_event_feed_multi_down(lookup->evas, e->multi.device, e->x, e->y, e->multi.radius, e->multi.radius_x, e->multi.radius_y, e->multi.pressure, e->multi.angle, e->multi.x, e->multi.y, flags, e->timestamp, NULL);
+ else
+ evas_event_feed_multi_up(lookup->evas, e->multi.device, e->x, e->y, e->multi.radius, e->multi.radius_x, e->multi.radius_y, e->multi.pressure, e->multi.angle, e->multi.x, e->multi.y, flags, e->timestamp, NULL);
+ }
+ return 1;
+}
+
+EAPI int
+ecore_event_evas_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Event_Mouse_Move *e;
+ Ecore_Input_Window *lookup;
+
+ e = event;
+ lookup = _ecore_event_window_match(e->window);
+ if (!lookup) return 1;
+ if (e->multi.device == 0)
+ {
+ ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
+ lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp);
+ }
+ else
+ {
+ evas_event_feed_multi_move(lookup->evas, e->multi.device, e->x, e->y, e->multi.radius, e->multi.radius_x, e->multi.radius_y, e->multi.pressure, e->multi.angle, e->multi.x, e->multi.y, e->timestamp, NULL);
+ }
+ return 1;
+}
+
+EAPI int
+ecore_event_evas_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_DOWN);
+}
+
+EAPI int
+ecore_event_evas_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP);
+}
+
+static int
+_ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io)
+{
+ Ecore_Input_Window *lookup;
+
+ lookup = _ecore_event_window_match(e->window);
+ if (!lookup) return 1;
+ ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
+ switch (io)
+ {
+ case ECORE_IN:
+ evas_event_feed_mouse_in(lookup->evas, e->timestamp, NULL);
+ break;
+ case ECORE_OUT:
+ evas_event_feed_mouse_out(lookup->evas, e->timestamp, NULL);
+ break;
+ default:
+ break;
+ }
+
+ lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp);
+ return 1;
+}
+
+EAPI int
+ecore_event_evas_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_DOWN);
+}
+
+EAPI int
+ecore_event_evas_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_UP);
+}
+
+EAPI int
+ecore_event_evas_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ Ecore_Event_Mouse_Wheel *e;
+ Ecore_Input_Window *lookup;
+
+ e = event;
+ lookup = _ecore_event_window_match(e->window);
+ if (!lookup) return 1;
+ ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
+ evas_event_feed_mouse_wheel(lookup->evas, e->direction, e->z, e->timestamp, NULL);
+ return 1;
+}
+
+EAPI int
+ecore_event_evas_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_IN);
+}
+
+EAPI int
+ecore_event_evas_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+ return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_OUT);
+}
+
+EAPI int
+ecore_event_evas_init(void)
+{
+ if (++_ecore_event_evas_init_count != 1)
+ return _ecore_event_evas_init_count;
+
+ _ecore_input_evas_log_dom = eina_log_domain_register("EcoreInputEvas", ECORE_INPUT_EVAS_DEFAULT_LOG_COLOR);
+ if (_ecore_input_evas_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the ecore input evas_module.");
+ return --_ecore_event_evas_init_count;
+ }
+
+ if (!ecore_init())
+ {
+ return --_ecore_event_evas_init_count;
+ }
+
+ if (!ecore_event_init())
+ {
+ goto shutdown_ecore;
+ }
+
+ ecore_event_evas_handlers[0] = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
+ ecore_event_evas_key_down,
+ NULL);
+ ecore_event_evas_handlers[1] = ecore_event_handler_add(ECORE_EVENT_KEY_UP,
+ ecore_event_evas_key_up,
+ NULL);
+ ecore_event_evas_handlers[2] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ ecore_event_evas_mouse_button_down,
+ NULL);
+ ecore_event_evas_handlers[3] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
+ ecore_event_evas_mouse_button_up,
+ NULL);
+ ecore_event_evas_handlers[4] = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
+ ecore_event_evas_mouse_move,
+ NULL);
+ ecore_event_evas_handlers[5] = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
+ ecore_event_evas_mouse_wheel,
+ NULL);
+ ecore_event_evas_handlers[6] = ecore_event_handler_add(ECORE_EVENT_MOUSE_IN,
+ ecore_event_evas_mouse_in,
+ NULL);
+ ecore_event_evas_handlers[7] = ecore_event_handler_add(ECORE_EVENT_MOUSE_OUT,
+ ecore_event_evas_mouse_out,
+ NULL);
+
+ _window_hash = eina_hash_pointer_new(free);
+
+ return _ecore_event_evas_init_count;
+
+ shutdown_ecore:
+ ecore_shutdown();
+
+ return --_ecore_event_evas_init_count;
+}
+
+EAPI int
+ecore_event_evas_shutdown(void)
+{
+ size_t i;
+
+ if (--_ecore_event_evas_init_count != 0)
+ return _ecore_event_evas_init_count;
+
+ eina_hash_free(_window_hash);
+ _window_hash = NULL;
+ for (i = 0; i < sizeof(ecore_event_evas_handlers) / sizeof(Ecore_Event_Handler *); i++)
+ {
+ ecore_event_handler_del(ecore_event_evas_handlers[i]);
+ ecore_event_evas_handlers[i] = NULL;
+ }
+
+ ecore_event_shutdown();
+ ecore_shutdown();
+
+ eina_log_domain_unregister(_ecore_input_evas_log_dom);
+ _ecore_input_evas_log_dom = -1;
+
+ return _ecore_event_evas_init_count;
+}
--- /dev/null
+#ifndef _ECORE_INPUT_PRIVATE_H
+#define _ECORE_INPUT_PRIVATE_H
+
+extern int _ecore_input_evas_log_dom;
+
+#ifdef ECORE_INPUT_EVAS_DEFAULT_LOG_COLOR
+#undef ECORE_INPUT_EVAS_DEFAULT_LOG_COLOR
+#endif
+
+#define ECORE_INPUT_EVAS_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_input_evas_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_input_evas_log_dom, __VA_ARGS__)
+
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_input_evas_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_input_evas_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+#undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_input_evas_log_dom, __VA_ARGS__)
+
+#endif
--- /dev/null
+.deps
+.libs
+Ecore_Ipc.h
+Makefile
+Makefile.in
+ecore_ipc.lo
+libecore_ipc.la
--- /dev/null
+#ifndef _ECORE_IPC_H
+#define _ECORE_IPC_H
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+/**
+ * @file Ecore_Ipc.h
+ * @brief Ecore inter-process communication functions.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ECORE_IPC_PRIVATE_H
+ typedef void Ecore_Ipc_Server; /**< An IPC connection handle */
+ typedef void Ecore_Ipc_Client; /**< An IPC connection handle */
+#endif
+
+/**
+ * Macros used for generic data packing
+ */
+EAPI unsigned short _ecore_ipc_swap_16(unsigned short v);
+EAPI unsigned int _ecore_ipc_swap_32(unsigned int v);
+EAPI unsigned long long _ecore_ipc_swap_64(unsigned long long v);
+
+#ifdef WORDS_BIGENDIAN
+#define ECORE_IPC_SWAP2NET64(x) _ecore_ipc_swap_64(x)
+#define ECORE_IPC_SWAP2CPU64(x) _ecore_ipc_swap_64(x)
+#define ECORE_IPC_SWAP2NET32(x) _ecore_ipc_swap_32(x)
+#define ECORE_IPC_SWAP2CPU32(x) _ecore_ipc_swap_32(x)
+#define ECORE_IPC_SWAP2NET16(x) _ecore_ipc_swap_16(x)
+#define ECORE_IPC_SWAP2CPU16(x) _ecore_ipc_swap_16(x)
+#define ECORE_IPC_SWAP2NET8(x) (x)
+#define ECORE_IPC_SWAP2CPU8(x) (x)
+#else
+#define ECORE_IPC_SWAP2NET64(x) (x)
+#define ECORE_IPC_SWAP2CPU64(x) (x)
+#define ECORE_IPC_SWAP2NET32(x) (x)
+#define ECORE_IPC_SWAP2CPU32(x) (x)
+#define ECORE_IPC_SWAP2NET16(x) (x)
+#define ECORE_IPC_SWAP2CPU16(x) (x)
+#define ECORE_IPC_SWAP2NET8(x) (x)
+#define ECORE_IPC_SWAP2CPU8(x) (x)
+#endif
+
+/* 1, 2, 4 and 8 byte datatypes */
+/* unpacking */
+#define ECORE_IPC_GET64(v)\
+ { \
+ p->v = ECORE_IPC_SWAP2CPU64(*(long long *)(ptr)); \
+ ptr += 8; \
+ }
+#define ECORE_IPC_GET32(v)\
+ { \
+ p->v = ECORE_IPC_SWAP2CPU32(*(int *)(ptr)); \
+ ptr += 4; \
+ }
+#define ECORE_IPC_GET16(v)\
+ { \
+ p->v = ECORE_IPC_SWAP2CPU16(*(short *)(ptr)); \
+ ptr += 2; \
+ }
+#define ECORE_IPC_GET8(v) \
+ { \
+ p->v = ECORE_IPC_SWAP2CPU8(*(char *)(ptr)); \
+ ptr += 1; \
+ }
+/* packing */
+#define ECORE_IPC_PUT64(v)\
+ { \
+ *(long long *)(ptr) = ECORE_IPC_SWAP2NET64(p->v); \
+ ptr += 8; \
+ }
+#define ECORE_IPC_PUT32(v)\
+ { \
+ *(int *)(ptr) = ECORE_IPC_SWAP2NET32(p->v); \
+ ptr += 4; \
+ }
+#define ECORE_IPC_PUT16(v)\
+ { \
+ *(short *)(ptr) = ECORE_IPC_SWAP2NET16(p->v); \
+ ptr += 2; \
+ }
+#define ECORE_IPC_PUT8(v) \
+ { \
+ *(char *)(ptr) = ECORE_IPC_SWAP2NET8(p->v); \
+ ptr += 1; \
+ }
+/* padding data */
+#define ECORE_IPC_PAD8() ptr += 1
+#define ECORE_IPC_PAD16() ptr += 2
+#define ECORE_IPC_PAD32() ptr += 4
+#define ECORE_IPC_PAD64() ptr += 8
+
+/* counting data when encoding lists */
+#define ECORE_IPC_CNT8() len += 1
+#define ECORE_IPC_CNT16() len += 2
+#define ECORE_IPC_CNT32() len += 4
+#define ECORE_IPC_CNT64() len += 8
+
+/* strings */
+#define ECORE_IPC_CHEKS() if (*((unsigned char *)d + s - 1) != 0) return 0;
+#define ECORE_IPC_GETS(v) \
+ { \
+ if (ptr < ((unsigned char *)d + s)) \
+ { \
+ p->v = (char *)ptr; \
+ ptr += strlen(p->v) + 1; \
+ } \
+ }
+#define ECORE_IPC_PUTS(v, l)\
+ { \
+ strcpy((char *)ptr, p->v); \
+ ptr += l + 1; \
+ }
+
+/* handy to calculate what sized block we need to alloc */
+#define ECORE_IPC_SLEN(l, v) ((l = strlen(p->v)) + 1)
+#define ECORE_IPC_CNTS(v) len += strlen(p->v) + 1
+
+/* saves typing function headers */
+#define ECORE_IPC_DEC_STRUCT_PROTO(x) static int x(void *d, int s, void *pp)
+#define ECORE_IPC_ENC_STRUCT_PROTO(x) static void *x(void *pp, int *s)
+#define ECORE_IPC_DEC_EINA_LIST_PROTO(x) static Eina_List *x(void *d, int s)
+#define ECORE_IPC_ENC_EINA_LIST_PROTO(x) static void *x(Eina_List *lp, int *s)
+
+
+/* decoder setup - saves typing. requires data packet of exact size, or fail */
+#define ECORE_IPC_DEC_STRUCT_HEAD_EXACT(typ, x) \
+ typ *p; \
+ unsigned char *ptr; \
+ p = (typ *)pp; \
+ if (!d) return 0; if (s != (x)) return 0; \
+ ptr = d;
+/* decoder setup - saves typing. requires data packet of a minimum size */
+#define ECORE_IPC_DEC_STRUCT_HEAD_MIN(typ, x) \
+ typ *p; \
+ unsigned char *ptr; \
+ p = (typ *)pp; \
+ if (!d) return 0; if (s < (x)) return 0; \
+ ptr = d;
+/* footer for the hell of it */
+#define ECORE_IPC_DEC_STRUCT_FOOT() return 1
+/* header for encoder - gives native strct type and size of flattened packet */
+#define ECORE_IPC_ENC_STRUCT_HEAD(typ, sz) \
+ typ *p; \
+ unsigned char *d, *ptr; \
+ int len; \
+ *s = 0; \
+ if(!pp) return NULL; \
+ p = (typ *)pp; \
+ len = sz; \
+ d = malloc(len); \
+ if (!d) return NULL; \
+ *s = len; \
+ ptr = d;
+/* footer for the hell of it */
+#define ECORE_IPC_ENC_STRUCT_FOOT() return d
+
+#define ECORE_IPC_DEC_EINA_LIST_HEAD(typ) \
+ unsigned char *ptr; \
+ Eina_List *l; \
+ typ *p; \
+ l = NULL; \
+ ptr = d; \
+ while(ptr < (unsigned char *)(d + s)) \
+ { \
+ p = malloc(sizeof(typ));
+
+#define ECORE_IPC_DEC_EINA_LIST_FOOT() \
+ l = eina_list_append(l, p); \
+ } \
+ return l
+#define ECORE_IPC_ENC_EINA_LIST_HEAD_START(typ) \
+ Eina_List *l; \
+ typ *p; \
+ unsigned char *d, *ptr; \
+ int len; \
+ *s = 0; \
+ len = 0; \
+ for (l = lp; l; l = l->next) \
+ { \
+ p = l->data;
+#define ECORE_IPC_ENC_EINA_LIST_HEAD_FINISH() \
+ } \
+ d = malloc(len); \
+ if(!d) return NULL; \
+ *s = len; \
+ ptr = d; \
+ for (l = lp; l; l = l->next) \
+ { \
+ p = l->data;
+
+#define ECORE_IPC_ENC_EINA_LIST_FOOT() \
+ } \
+ return d
+
+ typedef enum _Ecore_Ipc_Type
+ {
+ ECORE_IPC_LOCAL_USER,
+ ECORE_IPC_LOCAL_SYSTEM,
+ ECORE_IPC_REMOTE_SYSTEM,
+ ECORE_IPC_USE_SSL = 16
+ } Ecore_Ipc_Type;
+
+ typedef struct _Ecore_Ipc_Event_Client_Add Ecore_Ipc_Event_Client_Add;
+ typedef struct _Ecore_Ipc_Event_Client_Del Ecore_Ipc_Event_Client_Del;
+ typedef struct _Ecore_Ipc_Event_Server_Add Ecore_Ipc_Event_Server_Add;
+ typedef struct _Ecore_Ipc_Event_Server_Del Ecore_Ipc_Event_Server_Del;
+ typedef struct _Ecore_Ipc_Event_Client_Data Ecore_Ipc_Event_Client_Data;
+ typedef struct _Ecore_Ipc_Event_Server_Data Ecore_Ipc_Event_Server_Data;
+
+ struct _Ecore_Ipc_Event_Client_Add
+ {
+ Ecore_Ipc_Client *client;
+ };
+
+ struct _Ecore_Ipc_Event_Client_Del
+ {
+ Ecore_Ipc_Client *client;
+ };
+
+ struct _Ecore_Ipc_Event_Server_Add
+ {
+ Ecore_Ipc_Server *server;
+ };
+
+ struct _Ecore_Ipc_Event_Server_Del
+ {
+ Ecore_Ipc_Server *server;
+ };
+
+ struct _Ecore_Ipc_Event_Client_Data
+ {
+ Ecore_Ipc_Client *client;
+ /* FIXME: this needs to become an ipc message */
+ int major;
+ int minor;
+ int ref;
+ int ref_to;
+ int response;
+ void *data;
+ int size;
+ };
+
+ struct _Ecore_Ipc_Event_Server_Data
+ {
+ Ecore_Ipc_Server *server;
+ /* FIXME: this needs to become an ipc message */
+ int major;
+ int minor;
+ int ref;
+ int ref_to;
+ int response;
+ void *data;
+ int size;
+ };
+
+ EAPI extern int ECORE_IPC_EVENT_CLIENT_ADD;
+ EAPI extern int ECORE_IPC_EVENT_CLIENT_DEL;
+ EAPI extern int ECORE_IPC_EVENT_SERVER_ADD;
+ EAPI extern int ECORE_IPC_EVENT_SERVER_DEL;
+ EAPI extern int ECORE_IPC_EVENT_CLIENT_DATA;
+ EAPI extern int ECORE_IPC_EVENT_SERVER_DATA;
+
+ EAPI int ecore_ipc_init(void);
+ EAPI int ecore_ipc_shutdown(void);
+
+ /* FIXME: need to add protocol type parameter */
+ EAPI Ecore_Ipc_Server *ecore_ipc_server_add(Ecore_Ipc_Type type, const char *name, int port, const void *data);
+
+ /* FIXME: need to add protocol type parameter */
+ EAPI Ecore_Ipc_Server *ecore_ipc_server_connect(Ecore_Ipc_Type type, char *name, int port, const void *data);
+ EAPI void *ecore_ipc_server_del(Ecore_Ipc_Server *svr);
+ EAPI void *ecore_ipc_server_data_get(Ecore_Ipc_Server *svr);
+ EAPI int ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr);
+ EAPI Eina_List *ecore_ipc_server_clients_get(Ecore_Ipc_Server *svr);
+ /* FIXME: this needs to become an ipc message */
+ EAPI int ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, const void *data, int size);
+ EAPI void ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients);
+ EAPI void ecore_ipc_server_data_size_max_set(Ecore_Ipc_Server *srv, int size);
+ EAPI int ecore_ipc_server_data_size_max_get(Ecore_Ipc_Server *srv);
+ EAPI char *ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr);
+ EAPI void ecore_ipc_server_flush(Ecore_Ipc_Server *svr);
+
+ /* FIXME: this needs to become an ipc message */
+ EAPI int ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, const void *data, int size);
+ EAPI Ecore_Ipc_Server *ecore_ipc_client_server_get(Ecore_Ipc_Client *cl);
+ EAPI void *ecore_ipc_client_del(Ecore_Ipc_Client *cl);
+ EAPI void ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data);
+ EAPI void *ecore_ipc_client_data_get(Ecore_Ipc_Client *cl);
+ EAPI void ecore_ipc_client_data_size_max_set(Ecore_Ipc_Client *cl, int size);
+ EAPI int ecore_ipc_client_data_size_max_get(Ecore_Ipc_Client *cl);
+ EAPI char *ecore_ipc_client_ip_get(Ecore_Ipc_Client *cl);
+ EAPI void ecore_ipc_client_flush(Ecore_Ipc_Client *cl);
+
+ EAPI int ecore_ipc_ssl_available_get(void);
+ /* FIXME: need to add a callback to "ok" large ipc messages greater than */
+ /* a certain size (seurity/DOS attack safety) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_con \
+-I$(top_builddir)/src/lib/ecore_ipc \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
+-I$(top_srcdir)/src/lib/ecore_ipc \
+@SSL_CFLAGS@ @EINA_CFLAGS@
+
+if BUILD_ECORE_IPC
+
+lib_LTLIBRARIES = libecore_ipc.la
+include_HEADERS = \
+Ecore_Ipc.h
+
+libecore_ipc_la_SOURCES = \
+ecore_ipc.c
+
+libecore_ipc_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la \
+@SSL_LIBS@ \
+@EINA_LIBS@
+
+libecore_ipc_la_LDFLAGS = -no-undefined -version-info @version_info@ @ecore_ipc_release_info@
+
+endif
+
+EXTRA_DIST = ecore_ipc_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#ifdef HAVE_NETINET_IN_H
+# include <sys/types.h>
+# include <netinet/in.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Con.h"
+#include "ecore_ipc_private.h"
+#include "Ecore_Ipc.h"
+
+#define DLT_ZERO 0
+#define DLT_ONE 1
+#define DLT_SAME 2
+#define DLT_SHL 3
+#define DLT_SHR 4
+#define DLT_ADD8 5
+#define DLT_DEL8 6
+#define DLT_ADDU8 7
+#define DLT_DELU8 8
+#define DLT_ADD16 9
+#define DLT_DEL16 10
+#define DLT_ADDU16 11
+#define DLT_DELU16 12
+#define DLT_SET 13
+#define DLT_R1 14
+#define DLT_R2 15
+
+int _ecore_ipc_log_dom = -1;
+
+/* byte swappers - for dealing with big vs little endian machines */
+EAPI unsigned short
+_ecore_ipc_swap_16(unsigned short v)
+{
+ unsigned char *s, t;
+
+ s = (unsigned char *)(&v);
+ t = s[0]; s[0] = s[1]; s[1] = t;
+ return v;
+}
+
+EAPI unsigned int
+_ecore_ipc_swap_32(unsigned int v)
+{
+ unsigned char *s, t;
+
+ s = (unsigned char *)(&v);
+ t = s[0]; s[0] = s[3]; s[3] = t;
+ t = s[1]; s[1] = s[2]; s[2] = t;
+ return v;
+}
+
+EAPI unsigned long long
+_ecore_ipc_swap_64(unsigned long long v)
+{
+ unsigned char *s, t;
+
+ s = (unsigned char *)(&v);
+ t = s[0]; s[0] = s[7]; s[7] = t;
+ t = s[1]; s[1] = s[6]; s[6] = t;
+ t = s[2]; s[2] = s[5]; s[5] = t;
+ t = s[3]; s[3] = s[4]; s[4] = t;
+ return v;
+}
+
+static int _ecore_ipc_dlt_int(int out, int prev, int *mode);
+static int _ecore_ipc_ddlt_int(int in, int prev, int mode);
+
+static int
+_ecore_ipc_dlt_int(int out, int prev, int *mode)
+{
+ int dlt;
+
+ /* 0 byte */
+ if (out == 0)
+ {
+ *mode = DLT_ZERO;
+ return 0;
+ }
+ if (out == (int)0xffffffff)
+ {
+ *mode = DLT_ONE;
+ return 0;
+ }
+ if (out == prev)
+ {
+ *mode = DLT_SAME;
+ return 0;
+ }
+ if (out == prev << 1)
+ {
+ *mode = DLT_SHL;
+ return 0;
+ }
+ if (out == prev >> 1)
+ {
+ *mode = DLT_SHR;
+ return 0;
+ }
+ /* 1 byte */
+ dlt = out - prev;
+ if (!(dlt & 0xffffff00))
+ {
+ *mode = DLT_ADD8;
+ return dlt & 0xff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0xffffff00))
+ {
+ *mode = DLT_DEL8;
+ return dlt & 0xff;
+ }
+ dlt = out - prev;
+ if (!(dlt & 0x00ffffff))
+ {
+ *mode = DLT_ADDU8;
+ return (dlt >> 24) & 0xff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0x00ffffff))
+ {
+ *mode = DLT_DELU8;
+ return (dlt >> 24) & 0xff;
+ }
+ /* 2 byte */
+ dlt = out - prev;
+ if (!(dlt & 0xffff0000))
+ {
+ *mode = DLT_ADD16;
+ return dlt & 0xffff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0xffff0000))
+ {
+ *mode = DLT_DEL16;
+ return dlt & 0xffff;
+ }
+ dlt = out - prev;
+ if (!(dlt & 0x0000ffff))
+ {
+ *mode = DLT_ADDU16;
+ return (dlt >> 16) & 0xffff;
+ }
+ dlt = prev - out;
+ if (!(dlt & 0x0000ffff))
+ {
+ *mode = DLT_DELU16;
+ return (dlt >> 16) & 0xffff;
+ }
+ /* 4 byte */
+ *mode = DLT_SET;
+ return out;
+}
+
+static int
+_ecore_ipc_ddlt_int(int in, int prev, int mode)
+{
+ switch (mode)
+ {
+ case DLT_ZERO:
+ return 0;
+ break;
+ case DLT_ONE:
+ return 0xffffffff;
+ break;
+ case DLT_SAME:
+ return prev;
+ break;
+ case DLT_SHL:
+ return prev << 1;
+ break;
+ case DLT_SHR:
+ return prev >> 1;
+ break;
+ case DLT_ADD8:
+ return prev + in;
+ break;
+ case DLT_DEL8:
+ return prev - in;
+ break;
+ case DLT_ADDU8:
+ return prev + (in << 24);
+ break;
+ case DLT_DELU8:
+ return prev - (in << 24);
+ break;
+ case DLT_ADD16:
+ return prev + in;
+ break;
+ case DLT_DEL16:
+ return prev - in;
+ break;
+ case DLT_ADDU16:
+ return prev + (in << 16);
+ break;
+ case DLT_DELU16:
+ return prev - (in << 16);
+ break;
+ case DLT_SET:
+ return in;
+ break;
+ case DLT_R1:
+ return 0;
+ break;
+ case DLT_R2:
+ return 0;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int _ecore_ipc_event_client_add(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_client_del(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_server_add(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_server_del(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_client_data(void *data, int ev_type, void *ev);
+static int _ecore_ipc_event_server_data(void *data, int ev_type, void *ev);
+static void _ecore_ipc_event_client_add_free(void *data, void *ev);
+static void _ecore_ipc_event_client_del_free(void *data, void *ev);
+static void _ecore_ipc_event_client_data_free(void *data, void *ev);
+static void _ecore_ipc_event_server_add_free(void *data, void *ev);
+static void _ecore_ipc_event_server_del_free(void *data, void *ev);
+static void _ecore_ipc_event_server_data_free(void *data, void *ev);
+
+EAPI int ECORE_IPC_EVENT_CLIENT_ADD = 0;
+EAPI int ECORE_IPC_EVENT_CLIENT_DEL = 0;
+EAPI int ECORE_IPC_EVENT_SERVER_ADD = 0;
+EAPI int ECORE_IPC_EVENT_SERVER_DEL = 0;
+EAPI int ECORE_IPC_EVENT_CLIENT_DATA = 0;
+EAPI int ECORE_IPC_EVENT_SERVER_DATA = 0;
+
+static int _ecore_ipc_init_count = 0;
+static Eina_List *servers = NULL;
+static Ecore_Event_Handler *handler[6];
+
+/**
+ * @defgroup Ecore_IPC_Library_Group IPC Library Functions
+ *
+ * Functions that set up and shut down the Ecore IPC Library.
+ */
+
+/**
+ * Initialises the Ecore IPC library.
+ * @return Number of times the library has been initialised without
+ * being shut down.
+ * @ingroup Ecore_IPC_Library_Group
+ */
+EAPI int
+ecore_ipc_init(void)
+{
+ int i = 0;
+
+ if (++_ecore_ipc_init_count != 1)
+ return _ecore_ipc_init_count;
+ _ecore_ipc_log_dom = eina_log_domain_register("EcoreIpc", ECORE_IPC_DEFAULT_LOG_COLOR);
+ if(_ecore_ipc_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the Ecore IPC module.");
+ return --_ecore_ipc_init_count;
+ }
+ if (!ecore_con_init())
+ return --_ecore_ipc_init_count;
+
+ ECORE_IPC_EVENT_CLIENT_ADD = ecore_event_type_new();
+ ECORE_IPC_EVENT_CLIENT_DEL = ecore_event_type_new();
+ ECORE_IPC_EVENT_SERVER_ADD = ecore_event_type_new();
+ ECORE_IPC_EVENT_SERVER_DEL = ecore_event_type_new();
+ ECORE_IPC_EVENT_CLIENT_DATA = ecore_event_type_new();
+ ECORE_IPC_EVENT_SERVER_DATA = ecore_event_type_new();
+
+ handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD,
+ _ecore_ipc_event_client_add, NULL);
+ handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL,
+ _ecore_ipc_event_client_del, NULL);
+ handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD,
+ _ecore_ipc_event_server_add, NULL);
+ handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
+ _ecore_ipc_event_server_del, NULL);
+ handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA,
+ _ecore_ipc_event_client_data, NULL);
+ handler[i] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
+ _ecore_ipc_event_server_data, NULL);
+ return _ecore_ipc_init_count;
+}
+
+/**
+ * Shuts down the Ecore IPC library.
+ * @return Number of times the library has been initialised without being
+ * shut down.
+ * @ingroup Ecore_IPC_Library_Group
+ */
+EAPI int
+ecore_ipc_shutdown(void)
+{
+ int i;
+
+ if (--_ecore_ipc_init_count != 0)
+ return _ecore_ipc_init_count;
+
+ while (servers) ecore_ipc_server_del(eina_list_data_get(servers));
+
+ for (i = 0; i < 6; i++)
+ ecore_event_handler_del(handler[i]);
+
+ ecore_con_shutdown();
+ eina_log_domain_unregister(_ecore_ipc_log_dom);
+ _ecore_ipc_log_dom = -1;
+ return _ecore_ipc_init_count;
+}
+
+/**
+ * @defgroup Ecore_IPC_Server_Group IPC Server Functions
+ *
+ * Functions the deal with IPC server objects.
+ */
+
+/**
+ * Creates an IPC server that listens for connections.
+ *
+ * For more details about the @p compl_type, @p name and @p port
+ * parameters, see the @ref ecore_con_server_add documentation.
+ *
+ * @param compl_type The connection type.
+ * @param name Name to associate with the socket used for connection.
+ * @param port Number to identify with socket used for connection.
+ * @param data Data to associate with the IPC server.
+ * @return New IPC server. If there is an error, @c NULL is returned.
+ * @ingroup Ecore_IPC_Server_Group
+ * @todo Need to add protocol type parameter to this function.
+ */
+EAPI Ecore_Ipc_Server *
+ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, const void *data)
+{
+ Ecore_Ipc_Server *svr;
+ Ecore_Ipc_Type type;
+ Ecore_Con_Type extra = 0;
+
+ svr = calloc(1, sizeof(Ecore_Ipc_Server));
+ if (!svr) return NULL;
+ type = compl_type;
+ type &= ~ECORE_IPC_USE_SSL;
+ if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
+ switch (type)
+ {
+ case ECORE_IPC_LOCAL_USER:
+ svr->server = ecore_con_server_add(ECORE_CON_LOCAL_USER | extra, name, port, svr);
+ break;
+ case ECORE_IPC_LOCAL_SYSTEM:
+ svr->server = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
+ break;
+ case ECORE_IPC_REMOTE_SYSTEM:
+ svr->server = ecore_con_server_add(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
+ break;
+ default:
+ free(svr);
+ return NULL;
+ }
+ if (!svr->server)
+ {
+ free(svr);
+ return NULL;
+ }
+ svr->max_buf_size = 32 * 1024;
+ svr->data = (void *)data;
+ servers = eina_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
+ return svr;
+}
+
+/**
+ * Creates an IPC server object to represent the IPC server listening
+ * on the given port.
+ *
+ * For more details about the @p compl_type, @p name and @p port
+ * parameters, see the @ref ecore_con_server_connect documentation.
+ *
+ * @param compl_type The IPC connection type.
+ * @param name Name used to determine which socket to use for the
+ * IPC connection.
+ * @param port Number used to identify the socket to use for the
+ * IPC connection.
+ * @param data Data to associate with the server.
+ * @return A new IPC server. @c NULL is returned on error.
+ * @ingroup Ecore_IPC_Server_Group
+ * @todo Need to add protocol type parameter.
+ */
+EAPI Ecore_Ipc_Server *
+ecore_ipc_server_connect(Ecore_Ipc_Type compl_type, char *name, int port, const void *data)
+{
+ Ecore_Ipc_Server *svr;
+ Ecore_Ipc_Type type;
+ Ecore_Con_Type extra = 0;
+
+ svr = calloc(1, sizeof(Ecore_Ipc_Server));
+ if (!svr) return NULL;
+ type = compl_type;
+ type &= ~ECORE_IPC_USE_SSL;
+ if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL;
+ switch (type)
+ {
+ case ECORE_IPC_LOCAL_USER:
+ svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, svr);
+ break;
+ case ECORE_IPC_LOCAL_SYSTEM:
+ svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
+ break;
+ case ECORE_IPC_REMOTE_SYSTEM:
+ svr->server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr);
+ break;
+ default:
+ free(svr);
+ return NULL;
+ }
+ if (!svr->server)
+ {
+ free(svr);
+ return NULL;
+ }
+ svr->max_buf_size = -1;
+ svr->data = (void *)data;
+ servers = eina_list_append(servers, svr);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
+ return svr;
+}
+
+/**
+ * Closes the connection and frees the given IPC server.
+ * @param svr The given IPC server.
+ * @return The data associated with the server when it was created.
+ * @ingroup Ecore_IPC_Server_Group
+ */
+EAPI void *
+ecore_ipc_server_del(Ecore_Ipc_Server *svr)
+{
+ void *data;
+
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_del");
+ return NULL;
+ }
+ if (svr->delete_me) return NULL;
+
+ data = svr->data;
+ svr->data = NULL;
+ svr->delete_me = 1;
+ if (svr->event_count == 0)
+ {
+ Ecore_Ipc_Client *cl;
+
+ EINA_LIST_FREE(svr->clients, cl)
+ ecore_ipc_client_del(cl);
+ ecore_con_server_del(svr->server);
+ servers = eina_list_remove(servers, svr);
+
+ if (svr->buf) free(svr->buf);
+ ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
+ free(svr);
+ }
+ return data;
+}
+
+/**
+ * Retrieves the data associated with the given IPC server.
+ * @param svr The given IPC server.
+ * @return The associated data.
+ * @ingroup Ecore_IPC_Server_Group
+ */
+EAPI void *
+ecore_ipc_server_data_get(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_data_get");
+ return NULL;
+ }
+ return svr->data;
+}
+
+/**
+ * Retrieves whether the given IPC server is currently connected.
+ * @param svr The given IPC server.
+ * @return @c 1 if the server is connected. @c 0 otherwise.
+ * @ingroup Ecore_IPC_Server_Group
+ */
+EAPI int
+ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_connected_get");
+ return 0;
+ }
+ return ecore_con_server_connected_get(svr->server);
+}
+
+/**
+ * Retrieves the list of clients for this server.
+ * @param svr The given IPC server.
+ * @return An Eina_List with the clients.
+ * @ingroup Ecore_IPC_Server_Group
+ */
+EAPI Eina_List *
+ecore_ipc_server_clients_get(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_clients_get");
+ return NULL;
+ }
+ return svr->client_list;
+}
+
+#define SVENC(_member) \
+ d = _ecore_ipc_dlt_int(msg._member, svr->prev.o._member, &md); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htonl(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ *(dat + s + 2) = dd[2]; \
+ *(dat + s + 3) = dd[3]; \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htons(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ *(dat + s + 0) = (unsigned char)d; \
+ s += 1; \
+ }
+
+/**
+ * Sends a message to the given IPC server.
+ *
+ * The content of the parameters, excluding the @p svr paramter, is up to
+ * the client.
+ *
+ * @param svr The given IPC server.
+ * @param major Major opcode of the message.
+ * @param minor Minor opcode of the message.
+ * @param ref Message reference number.
+ * @param ref_to Reference number of the message this message refers to.
+ * @param response Requires response.
+ * @param data The data to send as part of the message.
+ * @param size Length of the data, in bytes, to send.
+ * @return Number of bytes sent. @c 0 is returned if there is an error.
+ * @ingroup Ecore_IPC_Server_Group
+ * @todo This function needs to become an IPC message.
+ * @todo Fix up the documentation: Make sure what ref_to and response are.
+ */
+EAPI int
+ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
+{
+ Ecore_Ipc_Msg_Head msg;
+ int ret;
+ int *head, md = 0, d, s;
+ unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
+
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_send");
+ return 0;
+ }
+ if (size < 0) size = 0;
+ msg.major = major;
+ msg.minor = minor;
+ msg.ref = ref;
+ msg.ref_to = ref_to;
+ msg.response = response;
+ msg.size = size;
+ head = (int *)dat;
+ s = 4;
+ SVENC(major);
+ *head = md;
+ SVENC(minor);
+ *head |= md << (4 * 1);
+ SVENC(ref);
+ *head |= md << (4 * 2);
+ SVENC(ref_to);
+ *head |= md << (4 * 3);
+ SVENC(response);
+ *head |= md << (4 * 4);
+ SVENC(size);
+ *head |= md << (4 * 5);
+ *head = htonl(*head);
+ svr->prev.o = msg;
+ ret = ecore_con_server_send(svr->server, dat, s);
+ if (size > 0) ret += ecore_con_server_send(svr->server, data, size);
+ return ret;
+}
+
+/**
+ * Sets a limit on the number of clients that can be handled concurrently
+ * by the given server, and a policy on what to do if excess clients try to
+ * connect.
+ * Beware that if you set this once ecore is already running, you may
+ * already have pending CLIENT_ADD events in your event queue. Those
+ * clients have already connected and will not be affected by this call.
+ * Only clients subsequently trying to connect will be affected.
+ * @param svr The given server.
+ * @param client_limit The maximum number of clients to handle
+ * concurrently. -1 means unlimited (default). 0
+ * effectively disables the server.
+ * @param reject_excess_clients Set to 1 to automatically disconnect
+ * excess clients as soon as they connect if you are
+ * already handling client_limit clients. Set to 0
+ * (default) to just hold off on the "accept()"
+ * system call until the number of active clients
+ * drops. This causes the kernel to queue up to 4096
+ * connections (or your kernel's limit, whichever is
+ * lower).
+ * @ingroup Ecore_Ipc_Server_Group
+ */
+EAPI void
+ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_client_limit_set");
+ return;
+ }
+ ecore_con_server_client_limit_set(svr->server, client_limit, reject_excess_clients);
+}
+
+/**
+ * Sets the max data payload size for an Ipc message in bytes
+ *
+ * @param svr The given server.
+ * @param size The maximum data payload size in bytes.
+ * @ingroup Ecore_Ipc_Server_Group
+ */
+EAPI void
+ecore_ipc_server_data_size_max_set(Ecore_Ipc_Server *svr, int size)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_data_size_max_set");
+ return;
+ }
+ svr->max_buf_size = size;
+}
+
+/**
+ * Gets the max data payload size for an Ipc message in bytes
+ *
+ * @param svr The given server.
+ * @return The maximum data payload in bytes.
+ * @ingroup Ecore_Ipc_Server_Group
+ */
+EAPI int
+ecore_ipc_server_data_size_max_get(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_data_size_max_get");
+ return -1;
+ }
+ return svr->max_buf_size;
+}
+
+/**
+ * Gets the IP address of a server that has been connected to.
+ *
+ * @param svr The given server.
+ * @return A pointer to an internal string that contains the IP address of
+ * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
+ * This string should not be modified or trusted to stay valid after
+ * deletion for the @p svr object. If no IP is known NULL is returned.
+ * @ingroup Ecore_Ipc_Server_Group
+ */
+EAPI char *
+ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_ip_get");
+ return NULL;
+ }
+ return ecore_con_server_ip_get(svr->server);
+}
+
+/**
+ * Flushes all pending data to the given server. Will return when done.
+ *
+ * @param svr The given server.
+ * @ingroup Ecore_Ipc_Server_Group
+ */
+EAPI void
+ecore_ipc_server_flush(Ecore_Ipc_Server *svr)
+{
+ if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER))
+ {
+ ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER,
+ "ecore_ipc_server_server_flush");
+ return;
+ }
+ ecore_con_server_flush(svr->server);
+}
+
+#define CLENC(_member) \
+ d = _ecore_ipc_dlt_int(msg._member, cl->prev.o._member, &md); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htonl(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ *(dat + s + 2) = dd[2]; \
+ *(dat + s + 3) = dd[3]; \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dd; \
+ dd = (unsigned char *)&v; \
+ v = d; \
+ v = htons(v); \
+ *(dat + s + 0) = dd[0]; \
+ *(dat + s + 1) = dd[1]; \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ *(dat + s) = (unsigned char)d; \
+ s += 1; \
+ }
+
+/**
+ * @defgroup Ecore_IPC_Client_Group IPC Client Functions
+ *
+ * Functions that deal with IPC client objects.
+ */
+
+/**
+ * Sends a message to the given IPC client.
+ * @param cl The given IPC client.
+ * @param major Major opcode of the message.
+ * @param minor Minor opcode of the message.
+ * @param ref Reference number of the message.
+ * @param ref_to Reference number of the message this message refers to.
+ * @param response Requires response.
+ * @param data The data to send as part of the message.
+ * @param size Length of the data, in bytes, to send.
+ * @return The number of bytes sent. @c 0 will be returned if there is
+ * an error.
+ * @ingroup Ecore_IPC_Client_Group
+ * @todo This function needs to become an IPC message.
+ * @todo Make sure ref_to and response parameters are described correctly.
+ */
+EAPI int
+ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, const void *data, int size)
+{
+ Ecore_Ipc_Msg_Head msg;
+ int ret;
+ int *head, md = 0, d, s;
+ unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)];
+
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_send");
+ return 0;
+ }
+ if (size < 0) size = 0;
+ msg.major = major;
+ msg.minor = minor;
+ msg.ref = ref;
+ msg.ref_to = ref_to;
+ msg.response = response;
+ msg.size = size;
+ head = (int *)dat;
+ s = 4;
+ CLENC(major);
+ *head = md;
+ CLENC(minor);
+ *head |= md << (4 * 1);
+ CLENC(ref);
+ *head |= md << (4 * 2);
+ CLENC(ref_to);
+ *head |= md << (4 * 3);
+ CLENC(response);
+ *head |= md << (4 * 4);
+ CLENC(size);
+ *head |= md << (4 * 5);
+ *head = htonl(*head);
+ cl->prev.o = msg;
+ ret = ecore_con_client_send(cl->client, dat, s);
+ if (size > 0) ret += ecore_con_client_send(cl->client, data, size);
+ return ret;
+}
+
+/**
+ * Retrieves the IPC server that the given IPC client is connected to.
+ * @param cl The given IPC client.
+ * @return The IPC server the IPC client is connected to.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+EAPI Ecore_Ipc_Server *
+ecore_ipc_client_server_get(Ecore_Ipc_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_server_get");
+ return NULL;
+ }
+ return (ecore_con_server_data_get(ecore_con_client_server_get(cl->client)));
+}
+
+/**
+ * Closes the connection and frees memory allocated to the given IPC
+ * client.
+ * @param cl The given client.
+ * @return Data associated with the client.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+EAPI void *
+ecore_ipc_client_del(Ecore_Ipc_Client *cl)
+{
+ void *data;
+ Ecore_Ipc_Server *svr;
+
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_del");
+ return NULL;
+ }
+ data = cl->data;
+ cl->data = NULL;
+ cl->delete_me = 1;
+ if (cl->event_count == 0)
+ {
+ svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
+ ecore_con_client_del(cl->client);
+ svr->clients = eina_list_remove(svr->clients, cl);
+ if (cl->buf) free(cl->buf);
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE);
+ free(cl);
+ }
+ return data;
+}
+
+/**
+ * Sets the IPC data associated with the given IPC client to @p data.
+ * @param cl The given IPC client.
+ * @param data The data to associate with the IPC client.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+EAPI void
+ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_data_set");
+ return;
+ }
+ cl->data = (void *)data;
+}
+
+/**
+ * Retrieves the data that has been associated with the given IPC client.
+ * @param cl The given client.
+ * @return The data associated with the IPC client.
+ * @ingroup Ecore_IPC_Client_Group
+ */
+EAPI void *
+ecore_ipc_client_data_get(Ecore_Ipc_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_data_get");
+ return NULL;
+ }
+ return cl->data;
+}
+
+/**
+ * Sets the max data payload size for an Ipc message in bytes
+ *
+ * @param client The given client.
+ * @param size The maximum data payload size in bytes.
+ * @ingroup Ecore_Ipc_Client_Group
+ */
+EAPI void
+ecore_ipc_client_data_size_max_set(Ecore_Ipc_Client *cl, int size)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_data_size_max_set");
+ return;
+ }
+ cl->max_buf_size = size;
+}
+
+/**
+ * Sets the max data payload size for an Ipc message in bytes
+ *
+ * @param cl The given client.
+ * @param size The maximum data payload size in bytes.
+ * @ingroup Ecore_Ipc_Client_Group
+ */
+EAPI int
+ecore_ipc_client_data_size_max_get(Ecore_Ipc_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_data_size_max_get");
+ return -1;
+ }
+ return cl->max_buf_size;
+}
+
+/**
+ * Gets the IP address of a client that has been connected to.
+ *
+ * @param cl The given client.
+ * @return A pointer to an internal string that contains the IP address of
+ * the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
+ * This string should not be modified or trusted to stay valid after
+ * deletion for the @p cl object. If no IP is known NULL is returned.
+ * @ingroup Ecore_Ipc_Client_Group
+ */
+EAPI char *
+ecore_ipc_client_ip_get(Ecore_Ipc_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_ip_get");
+ return NULL;
+ }
+ return ecore_con_client_ip_get(cl->client);
+}
+
+/**
+ * Flushes all pending data to the given client. Will return when done.
+ *
+ * @param cl The given client.
+ * @ingroup Ecore_Ipc_Client_Group
+ */
+EAPI void
+ecore_ipc_client_flush(Ecore_Ipc_Client *cl)
+{
+ if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT))
+ {
+ ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT,
+ "ecore_ipc_client_flush");
+ return;
+ }
+ ecore_con_client_flush(cl->client);
+}
+
+/**
+ * Returns if SSL support is available
+ * @return 1 if SSL is available, 0 if it is not.
+ * @ingroup Ecore_Con_Client_Group
+ */
+EAPI int
+ecore_ipc_ssl_available_get(void)
+{
+ return ecore_con_ssl_available_get();
+}
+
+
+static int
+_ecore_ipc_event_client_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Add *e;
+
+ e = ev;
+ if (!eina_list_data_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Client *cl;
+ Ecore_Ipc_Server *svr;
+
+ cl = calloc(1, sizeof(Ecore_Ipc_Client));
+ if (!cl) return 0;
+ svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
+ ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT);
+ cl->client = e->client;
+ cl->max_buf_size = 32 * 1024;
+ ecore_con_client_data_set(cl->client, (void *)cl);
+ svr->clients = eina_list_append(svr->clients, cl);
+ svr->client_list = eina_list_append(svr->client_list, cl);
+ if (!cl->delete_me)
+ {
+ Ecore_Ipc_Event_Client_Add *e2;
+
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Add));
+ if (e2)
+ {
+ cl->event_count++;
+ e2->client = cl;
+ ecore_event_add(ECORE_IPC_EVENT_CLIENT_ADD, e2,
+ _ecore_ipc_event_client_add_free, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_ipc_event_client_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Del *e;
+
+ e = ev;
+ if (!eina_list_data_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Client *cl;
+
+ cl = ecore_con_client_data_get(e->client);
+ {
+ Ecore_Ipc_Event_Client_Del *e2;
+ Ecore_Ipc_Server *svr;
+
+ svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client));
+ svr->client_list = eina_list_remove(svr->client_list, cl);
+ if (!cl->delete_me)
+ {
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Del));
+ if (e2)
+ {
+ cl->event_count++;
+ e2->client = cl;
+ ecore_event_add(ECORE_IPC_EVENT_CLIENT_DEL, e2,
+ _ecore_ipc_event_client_del_free, NULL);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_ipc_event_server_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Add *e;
+
+ e = ev;
+ if (!eina_list_data_find(servers, ecore_con_server_data_get(e->server))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Server *svr;
+
+ svr = ecore_con_server_data_get(e->server);
+ if (!svr->delete_me)
+ {
+ Ecore_Ipc_Event_Server_Add *e2;
+
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Add));
+ if (e2)
+ {
+ svr->event_count++;
+ e2->server = svr;
+ ecore_event_add(ECORE_IPC_EVENT_SERVER_ADD, e2,
+ _ecore_ipc_event_server_add_free, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+_ecore_ipc_event_server_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Del *e;
+
+ e = ev;
+ if (!eina_list_data_find(servers, ecore_con_server_data_get(e->server))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Server *svr;
+
+ svr = ecore_con_server_data_get(e->server);
+ if (!svr->delete_me)
+ {
+ Ecore_Ipc_Event_Server_Del *e2;
+
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Del));
+ if (e2)
+ {
+ svr->event_count++;
+ e2->server = svr;
+ ecore_event_add(ECORE_IPC_EVENT_SERVER_DEL, e2,
+ _ecore_ipc_event_server_del_free, NULL);
+ }
+ }
+ }
+ return 0;
+}
+
+#define CLSZ(_n) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) s += 4; \
+ else if (md >= DLT_ADD16) s += 2; \
+ else if (md >= DLT_ADD8) s += 1;
+
+#define CLDEC(_n, _member) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(cl->buf + offset + s + 0); \
+ dv[1] = *(cl->buf + offset + s + 1); \
+ dv[2] = *(cl->buf + offset + s + 2); \
+ dv[3] = *(cl->buf + offset + s + 3); \
+ d = (int)ntohl(v); \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(cl->buf + offset + s + 0); \
+ dv[1] = *(cl->buf + offset + s + 1); \
+ d = (int)ntohs(v); \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ unsigned char v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(cl->buf + offset + s + 0); \
+ d = (int)v; \
+ s += 1; \
+ } \
+ msg._member = _ecore_ipc_ddlt_int(d, cl->prev.i._member, md);
+
+static int
+_ecore_ipc_event_client_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Client_Data *e;
+
+ e = ev;
+ if (!eina_list_data_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Client *cl;
+ Ecore_Ipc_Msg_Head msg;
+ int offset = 0;
+ unsigned char *buf;
+
+ cl = ecore_con_client_data_get(e->client);
+
+ if (!cl->buf)
+ {
+ cl->buf_size = e->size;
+ cl->buf = e->data;
+ e->data = NULL; /* take it out of the old event */
+ }
+ else
+ {
+ buf = realloc(cl->buf, cl->buf_size + e->size);
+ if (!buf)
+ {
+ free(cl->buf);
+ cl->buf = 0;
+ cl->buf_size = 0;
+ return 0;
+ }
+ cl->buf = buf;
+ memcpy(cl->buf + cl->buf_size, e->data, e->size);
+ cl->buf_size += e->size;
+ }
+ /* examine header */
+ redo:
+ if ((cl->buf_size - offset) >= (int)sizeof(int))
+ {
+ int s, md, d = 0, head;
+ unsigned char *dd;
+
+ dd = (unsigned char *)&head;
+ dd[0] = *(cl->buf + offset + 0);
+ dd[1] = *(cl->buf + offset + 1);
+ dd[2] = *(cl->buf + offset + 2);
+ dd[3] = *(cl->buf + offset + 3);
+ head = ntohl(head);
+ dd = (unsigned char *)&d;
+ s = 4;
+ CLSZ(0);
+ CLSZ(1);
+ CLSZ(2);
+ CLSZ(3);
+ CLSZ(4);
+ CLSZ(5);
+ if ((cl->buf_size - offset) < s)
+ {
+ if (offset > 0) goto scroll;
+ return 0;
+ }
+
+ s = 4;
+ CLDEC(0, major);
+ CLDEC(1, minor);
+ CLDEC(2, ref);
+ CLDEC(3, ref_to);
+ CLDEC(4, response);
+ CLDEC(5, size);
+ if (msg.size < 0) msg.size = 0;
+ /* there is enough data in the buffer for a full message */
+ if ((cl->buf_size - offset) >= (s + msg.size))
+ {
+ Ecore_Ipc_Event_Client_Data *e2;
+ Ecore_Ipc_Server *svr;
+ int max, max2;
+
+ buf = NULL;
+ svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client));
+ max = svr->max_buf_size;
+ max2 = cl->max_buf_size;
+ if ((max >= 0) && (max2 >= 0))
+ {
+ if (max2 < max) max = max2;
+ }
+ else
+ {
+ if (max < 0) max = max2;
+ }
+ if ((max < 0) || (msg.size <= max))
+ {
+ if (msg.size > 0)
+ {
+ buf = malloc(msg.size);
+ if (!buf) return 0;
+ memcpy(buf, cl->buf + offset + s, msg.size);
+ }
+ if (!cl->delete_me)
+ {
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Data));
+ if (e2)
+ {
+ cl->event_count++;
+ e2->client = cl;
+ e2->major = msg.major;
+ e2->minor = msg.minor;
+ e2->ref = msg.ref;
+ e2->ref_to = msg.ref_to;
+ e2->response = msg.response;
+ e2->size = msg.size;
+ e2->data = buf;
+ ecore_event_add(ECORE_IPC_EVENT_CLIENT_DATA, e2,
+ _ecore_ipc_event_client_data_free,
+ NULL);
+ }
+ }
+ }
+ cl->prev.i = msg;
+ offset += (s + msg.size);
+ if (cl->buf_size == offset)
+ {
+ free(cl->buf);
+ cl->buf = NULL;
+ cl->buf_size = 0;
+ return 0;
+ }
+ goto redo;
+ }
+ else goto scroll;
+ }
+ else
+ {
+ scroll:
+ buf = malloc(cl->buf_size - offset);
+ if (!buf)
+ {
+ free(cl->buf);
+ cl->buf = NULL;
+ cl->buf_size = 0;
+ return 0;
+ }
+ memcpy(buf, cl->buf + offset, cl->buf_size - offset);
+ free(cl->buf);
+ cl->buf = buf;
+ cl->buf_size -= offset;
+ }
+ }
+ return 0;
+}
+
+#define SVSZ(_n) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) s += 4; \
+ else if (md >= DLT_ADD16) s += 2; \
+ else if (md >= DLT_ADD8) s += 1;
+
+#define SVDEC(_n, _member) \
+ md = ((head >> (4 * _n)) & 0xf); \
+ if (md >= DLT_SET) \
+ { \
+ unsigned int v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(svr->buf + offset + s + 0); \
+ dv[1] = *(svr->buf + offset + s + 1); \
+ dv[2] = *(svr->buf + offset + s + 2); \
+ dv[3] = *(svr->buf + offset + s + 3); \
+ d = (int)ntohl(v); \
+ s += 4; \
+ } \
+ else if (md >= DLT_ADD16) \
+ { \
+ unsigned short v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(svr->buf + offset + s + 0); \
+ dv[1] = *(svr->buf + offset + s + 1); \
+ d = (int)ntohs(v); \
+ s += 2; \
+ } \
+ else if (md >= DLT_ADD8) \
+ { \
+ unsigned char v; \
+ unsigned char *dv; \
+ dv = (unsigned char *)&v; \
+ dv[0] = *(svr->buf + offset + s + 0); \
+ d = (int)v; \
+ s += 1; \
+ } \
+ msg._member = _ecore_ipc_ddlt_int(d, svr->prev.i._member, md);
+
+static int
+_ecore_ipc_event_server_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+{
+ Ecore_Con_Event_Server_Data *e;
+
+ e = ev;
+ if (!eina_list_data_find(servers, ecore_con_server_data_get(e->server))) return 1;
+ /* handling code here */
+ {
+ Ecore_Ipc_Server *svr;
+ Ecore_Ipc_Msg_Head msg;
+ int offset = 0;
+ unsigned char *buf;
+
+ svr = ecore_con_server_data_get(e->server);
+
+ if (!svr->buf)
+ {
+ svr->buf_size = e->size;
+ svr->buf = e->data;
+ e->data = NULL; /* take it out of the old event */
+ }
+ else
+ {
+ buf = realloc(svr->buf, svr->buf_size + e->size);
+ if (!buf)
+ {
+ free(svr->buf);
+ svr->buf = 0;
+ svr->buf_size = 0;
+ return 0;
+ }
+ svr->buf = buf;
+ memcpy(svr->buf + svr->buf_size, e->data, e->size);
+ svr->buf_size += e->size;
+ }
+ /* examine header */
+ redo:
+ if ((svr->buf_size - offset) >= (int)sizeof(int))
+ {
+ int s, md, d = 0, head;
+ unsigned char *dd;
+
+ dd = (unsigned char *)&head;
+ dd[0] = *(svr->buf + offset + 0);
+ dd[1] = *(svr->buf + offset + 1);
+ dd[2] = *(svr->buf + offset + 2);
+ dd[3] = *(svr->buf + offset + 3);
+ head = ntohl(head);
+ dd = (unsigned char *)&d;
+ s = 4;
+ SVSZ(0);
+ SVSZ(1);
+ SVSZ(2);
+ SVSZ(3);
+ SVSZ(4);
+ SVSZ(5);
+ if ((svr->buf_size - offset) < s)
+ {
+ if (offset > 0) goto scroll;
+ return 0;
+ }
+
+ s = 4;
+ SVDEC(0, major);
+ SVDEC(1, minor);
+ SVDEC(2, ref);
+ SVDEC(3, ref_to);
+ SVDEC(4, response);
+ SVDEC(5, size);
+ if (msg.size < 0) msg.size = 0;
+ /* there is enough data in the buffer for a full message */
+ if ((svr->buf_size - offset) >= (s + msg.size))
+ {
+ Ecore_Ipc_Event_Server_Data *e2;
+ int max;
+
+ buf = NULL;
+ max = svr->max_buf_size;
+ if ((max < 0) || (msg.size <= max))
+ {
+ if (msg.size > 0)
+ {
+ buf = malloc(msg.size);
+ if (!buf) return 0;
+ memcpy(buf, svr->buf + offset + s, msg.size);
+ }
+ if (!svr->delete_me)
+ {
+ e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Data));
+ if (e2)
+ {
+ svr->event_count++;
+ e2->server = svr;
+ e2->major = msg.major;
+ e2->minor = msg.minor;
+ e2->ref = msg.ref;
+ e2->ref_to = msg.ref_to;
+ e2->response = msg.response;
+ e2->size = msg.size;
+ e2->data = buf;
+ ecore_event_add(ECORE_IPC_EVENT_SERVER_DATA, e2,
+ _ecore_ipc_event_server_data_free,
+ NULL);
+ }
+ }
+ }
+ svr->prev.i = msg;
+ offset += (s + msg.size);
+ if (svr->buf_size == offset)
+ {
+ free(svr->buf);
+ svr->buf = NULL;
+ svr->buf_size = 0;
+ return 0;
+ }
+ goto redo;
+ }
+ else goto scroll;
+ }
+ else
+ {
+ scroll:
+ buf = malloc(svr->buf_size - offset);
+ if (!buf)
+ {
+ free(svr->buf);
+ svr->buf = NULL;
+ svr->buf_size = 0;
+ return 0;
+ }
+ memcpy(buf, svr->buf + offset, svr->buf_size - offset);
+ free(svr->buf);
+ svr->buf = buf;
+ svr->buf_size -= offset;
+ }
+ }
+ return 0;
+}
+
+static void
+_ecore_ipc_event_client_add_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Client_Add *e;
+
+ e = ev;
+ e->client->event_count--;
+ if ((e->client->event_count == 0) && (e->client->delete_me))
+ ecore_ipc_client_del(e->client);
+ free(e);
+}
+
+static void
+_ecore_ipc_event_client_del_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Client_Del *e;
+
+ e = ev;
+ e->client->event_count--;
+ if ((e->client->event_count == 0) && (e->client->delete_me))
+ ecore_ipc_client_del(e->client);
+ free(e);
+}
+
+static void
+_ecore_ipc_event_client_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Client_Data *e;
+
+ e = ev;
+ e->client->event_count--;
+ if (e->data) free(e->data);
+ if ((e->client->event_count == 0) && (e->client->delete_me))
+ ecore_ipc_client_del(e->client);
+ free(e);
+}
+
+static void
+_ecore_ipc_event_server_add_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Server_Add *e;
+
+ e = ev;
+ e->server->event_count--;
+ if ((e->server->event_count == 0) && (e->server->delete_me))
+ ecore_ipc_server_del(e->server);
+ free(e);
+}
+
+static void
+_ecore_ipc_event_server_del_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Server_Add *e;
+
+ e = ev;
+ e->server->event_count--;
+ if ((e->server->event_count == 0) && (e->server->delete_me))
+ ecore_ipc_server_del(e->server);
+ free(e);
+}
+
+static void
+_ecore_ipc_event_server_data_free(void *data __UNUSED__, void *ev)
+{
+ Ecore_Ipc_Event_Server_Data *e;
+
+ e = ev;
+ if (e->data) free(e->data);
+ e->server->event_count--;
+ if ((e->server->event_count == 0) && (e->server->delete_me))
+ ecore_ipc_server_del(e->server);
+ free(e);
+}
--- /dev/null
+#ifndef _ECORE_IPC_PRIVATE_H
+#define _ECORE_IPC_PRIVATE_H
+
+
+extern int _ecore_ipc_log_dom;
+
+#ifdef ECORE_IPC_DEFAULT_LOG_COLOR
+# undef ECORE_IPC_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_IPC_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_ipc_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_ipc_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_ipc_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_ipc_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_ipc_log_dom, __VA_ARGS__)
+
+#if USE_GNUTLS_OPENSSL
+# include <gnutls/openssl.h>
+#elif USE_OPENSSL
+# include <openssl/ssl.h>
+#endif
+
+#define ECORE_MAGIC_IPC_SERVER 0x87786556
+#define ECORE_MAGIC_IPC_CLIENT 0x78875665
+
+typedef struct _Ecore_Ipc_Client Ecore_Ipc_Client;
+typedef struct _Ecore_Ipc_Server Ecore_Ipc_Server;
+typedef struct _Ecore_Ipc_Msg_Head Ecore_Ipc_Msg_Head;
+
+
+#ifdef __sgi
+#pragma pack 4
+#endif
+struct _Ecore_Ipc_Msg_Head
+{
+ int major;
+ int minor;
+ int ref;
+ int ref_to;
+ int response;
+ int size;
+}
+#ifdef _GNU_C_
+__attribute__ ((packed));
+#endif
+;
+#ifdef __sgi
+#pragma pack 0
+#endif
+
+struct _Ecore_Ipc_Client
+{
+ ECORE_MAGIC;
+ Ecore_Con_Client *client;
+ void *data;
+ unsigned char *buf;
+ int buf_size;
+ int max_buf_size;
+
+ struct {
+ Ecore_Ipc_Msg_Head i, o;
+ } prev;
+
+ int event_count;
+ char delete_me : 1;
+};
+
+struct _Ecore_Ipc_Server
+{
+ ECORE_MAGIC;
+ Ecore_Con_Server *server;
+ Eina_List *clients;
+ Eina_List *client_list;
+ void *data;
+ unsigned char *buf;
+ int buf_size;
+ int max_buf_size;
+
+ struct {
+ Ecore_Ipc_Msg_Head i, o;
+ } prev;
+
+ int event_count;
+ char delete_me : 1;
+};
+
+#endif
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+*.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef _ECORE_SDL_H
+#define _ECORE_SDL_H
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_SDL_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_SDL_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+/**
+ * @file
+ * @brief Ecore SDL system functions.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EAPI extern int ECORE_SDL_EVENT_KEY_DOWN; /**< SDL Key Down event */
+EAPI extern int ECORE_SDL_EVENT_KEY_UP; /**< SDL Key Up event */
+EAPI extern int ECORE_SDL_EVENT_MOUSE_BUTTON_DOWN; /**< SDL Mouse Down event */
+EAPI extern int ECORE_SDL_EVENT_MOUSE_BUTTON_UP; /**< SDL Mouse Up event */
+EAPI extern int ECORE_SDL_EVENT_MOUSE_MOVE; /**< SDL Mouse Move event */
+EAPI extern int ECORE_SDL_EVENT_MOUSE_WHEEL; /**< SDL Mouse Wheel event */
+EAPI extern int ECORE_SDL_EVENT_GOT_FOCUS; /**< SDL Mouse Wheel event */
+EAPI extern int ECORE_SDL_EVENT_LOST_FOCUS; /**< SDL Mouse Wheel event */
+EAPI extern int ECORE_SDL_EVENT_RESIZE;
+EAPI extern int ECORE_SDL_EVENT_EXPOSE;
+
+typedef struct _Ecore_Sdl_Event_Key_Down Ecore_Sdl_Event_Key_Down;
+struct _Ecore_Sdl_Event_Key_Down /** SDL Key Down event */
+{
+ const char *keyname; /**< The name of the key that was pressed */
+ const char *keycompose; /**< The UTF-8 string conversion if any */
+ unsigned int time;
+};
+
+typedef struct _Ecore_Sdl_Event_Key_Up Ecore_Sdl_Event_Key_Up;
+struct _Ecore_Sdl_Event_Key_Up /** SDL Key Up event */
+{
+ const char *keyname; /**< The name of the key that was released */
+ const char *keycompose; /**< The UTF-8 string conversion if any */
+ unsigned int time;
+};
+
+typedef struct _Ecore_Sdl_Event_Mouse_Button_Down Ecore_Sdl_Event_Mouse_Button_Down;
+struct _Ecore_Sdl_Event_Mouse_Button_Down /** SDL Mouse Down event */
+{
+ int button; /**< Mouse button that was pressed (1 - 32) */
+ int x; /**< Mouse co-ordinates when mouse button was pressed */
+ int y; /**< Mouse co-ordinates when mouse button was pressed */
+ int double_click : 1; /**< Set if click was a double click */
+ int triple_click : 1; /**< Set if click was a triple click */
+ unsigned int time;
+};
+
+typedef struct _Ecore_Sdl_Event_Mouse_Button_Up Ecore_Sdl_Event_Mouse_Button_Up;
+struct _Ecore_Sdl_Event_Mouse_Button_Up /** SDL Mouse Up event */
+{
+ int button; /**< Mouse button that was released (1 - 32) */
+ int x; /**< Mouse co-ordinates when mouse button was raised */
+ int y; /**< Mouse co-ordinates when mouse button was raised */
+ int double_click : 1; /**< Set if click was a double click */
+ int triple_click : 1; /**< Set if click was a triple click */
+ unsigned int time;
+};
+
+typedef struct _Ecore_Sdl_Event_Mouse_Move Ecore_Sdl_Event_Mouse_Move;
+struct _Ecore_Sdl_Event_Mouse_Move /** SDL Mouse Move event */
+{
+ int x; /**< Mouse co-ordinates where the mouse cursor moved to */
+ int y; /**< Mouse co-ordinates where the mouse cursor moved to */
+ unsigned int time;
+};
+
+typedef struct _Ecore_Sdl_Event_Mouse_Wheel Ecore_Sdl_Event_Mouse_Wheel;
+struct _Ecore_Sdl_Event_Mouse_Wheel /** SDL Mouse Wheel event */
+{
+ int x,y;
+ int direction; /* 0 = vertical, 1 = horizontal */
+ int wheel; /* value 1 (left/up), -1 (right/down) */
+ unsigned int time;
+};
+
+typedef struct _Ecore_Sdl_Event_Video_Resize Ecore_Sdl_Event_Video_Resize;
+struct _Ecore_Sdl_Event_Video_Resize
+{
+ int w;
+ int h;
+};
+
+EAPI int ecore_sdl_init(const char *name);
+EAPI int ecore_sdl_shutdown(void);
+EAPI void ecore_sdl_feed_events(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+#ifndef ECORE_SDL_KEYS_H__
+# define ECORE_SDL_KEYS_H__
+
+struct _ecore_sdl_keys_s
+{
+ int code;
+ const char* name;
+ const char* compose;
+};
+
+static const struct _ecore_sdl_keys_s keystable[] =
+{
+ { SDLK_UNKNOWN, "0x00", "" },
+ { SDLK_FIRST, "First", "First" },
+ { SDLK_BACKSPACE, "BackSpace", "\010" },
+ { SDLK_TAB, "Tab", "\011" },
+ { SDLK_CLEAR, "Clear", "Clear" },
+ { SDLK_RETURN, "Return", "\015" },
+ { SDLK_PAUSE, "Pause", "Pause" },
+ { SDLK_ESCAPE, "Escape", "\033" },
+ { SDLK_SPACE, "space", " " },
+ { SDLK_EXCLAIM, "exclam", "!" },
+ { SDLK_QUOTEDBL, "quotedbl", "\"" },
+ { SDLK_HASH, "numbersign", "#" },
+ { SDLK_DOLLAR, "dollar", "$" },
+ { SDLK_AMPERSAND, "ampersand", "&" },
+ { SDLK_QUOTE, "apostrophe", "'" },
+ { SDLK_LEFTPAREN, "parenleft", "(" },
+ { SDLK_RIGHTPAREN, "parenright", ")" },
+ { SDLK_ASTERISK, "asterik", "*" },
+ { SDLK_PLUS, "plus", "+" },
+ { SDLK_COMMA, "comma", "," },
+ { SDLK_MINUS, "minus", "-" },
+ { SDLK_PERIOD, "period", "." },
+ { SDLK_SLASH, "slash", "/" },
+ { SDLK_0, "0", "0" },
+ { SDLK_1, "1", "1" },
+ { SDLK_2, "2", "2" },
+ { SDLK_3, "3", "3" },
+ { SDLK_4, "4", "4" },
+ { SDLK_5, "5", "5" },
+ { SDLK_6, "6", "6" },
+ { SDLK_7, "7", "7" },
+ { SDLK_8, "8", "8" },
+ { SDLK_9, "9", "9" },
+ { SDLK_COLON, "colon", ":" },
+ { SDLK_SEMICOLON, "semicolon", ";" },
+ { SDLK_LESS, "less", "<" },
+ { SDLK_EQUALS, "equal", "=" },
+ { SDLK_GREATER, "greater", ">" },
+ { SDLK_QUESTION, "question", "?" },
+ { SDLK_AT, "at", "@" },
+
+ /* Skip uppercase letters */
+ { SDLK_LEFTBRACKET, "bracketleft", "[" },
+ { SDLK_BACKSLASH, "backslash", "\\" },
+ { SDLK_RIGHTBRACKET, "bracketright", "]" },
+ { SDLK_CARET, "asciicircumm", "^" },
+ { SDLK_UNDERSCORE, "underscore", "_" },
+ { SDLK_BACKQUOTE, "asciitilde", "`" },
+ { SDLK_a, "a", "a" },
+ { SDLK_b, "b", "b" },
+ { SDLK_c, "c", "c" },
+ { SDLK_d, "d", "d" },
+ { SDLK_e, "e", "e" },
+ { SDLK_f, "f", "f" },
+ { SDLK_g, "g", "g" },
+ { SDLK_h, "h", "h" },
+ { SDLK_i, "i", "i" },
+ { SDLK_j, "j", "j" },
+ { SDLK_k, "k", "k" },
+ { SDLK_l, "l", "l" },
+ { SDLK_m, "m", "m" },
+ { SDLK_n, "n", "n" },
+ { SDLK_o, "o", "o" },
+ { SDLK_p, "p", "p" },
+ { SDLK_q, "q", "q" },
+ { SDLK_r, "r", "r" },
+ { SDLK_s, "s", "s" },
+ { SDLK_t, "t", "t" },
+ { SDLK_u, "u", "u" },
+ { SDLK_v, "v", "v" },
+ { SDLK_w, "w", "w" },
+ { SDLK_x, "x", "x" },
+ { SDLK_y, "y", "y" },
+ { SDLK_z, "z", "z" },
+ { SDLK_DELETE, "Delete", "\177" },
+ /* End of ASCII mapped keysyms */
+
+ /* International keyboard syms */
+ { SDLK_WORLD_0, "w0", "" }, /* 0xA0 */
+ { SDLK_WORLD_1, "w1", "" },
+ { SDLK_WORLD_2, "w2", "" },
+ { SDLK_WORLD_3, "w3", "" },
+ { SDLK_WORLD_4, "w4", "" },
+ { SDLK_WORLD_5, "w5", "" },
+ { SDLK_WORLD_6, "w6", "" },
+ { SDLK_WORLD_7, "w7", "" },
+ { SDLK_WORLD_8, "w8", "" },
+ { SDLK_WORLD_9, "w9", "" },
+ { SDLK_WORLD_10, "w10", "" },
+ { SDLK_WORLD_11, "w11", "" },
+ { SDLK_WORLD_12, "w12", "" },
+ { SDLK_WORLD_13, "w13", "" },
+ { SDLK_WORLD_14, "w14", "" },
+ { SDLK_WORLD_15, "w15", "" },
+ { SDLK_WORLD_16, "w16", "" },
+ { SDLK_WORLD_17, "w17", "" },
+ { SDLK_WORLD_18, "w18", "" },
+ { SDLK_WORLD_19, "w19", "" },
+ { SDLK_WORLD_20, "w20", "" },
+ { SDLK_WORLD_21, "w21", "" },
+ { SDLK_WORLD_22, "w22", "" },
+ { SDLK_WORLD_23, "w23", "" },
+ { SDLK_WORLD_24, "w24", "" },
+ { SDLK_WORLD_25, "w25", "" },
+ { SDLK_WORLD_26, "w26", "" },
+ { SDLK_WORLD_27, "w27", "" },
+ { SDLK_WORLD_28, "w28", "" },
+ { SDLK_WORLD_29, "w29", "" },
+ { SDLK_WORLD_30, "w30", "" },
+ { SDLK_WORLD_31, "w31", "" },
+ { SDLK_WORLD_32, "w32", "" },
+ { SDLK_WORLD_33, "w33", "" },
+ { SDLK_WORLD_34, "w34", "" },
+ { SDLK_WORLD_35, "w35", "" },
+ { SDLK_WORLD_36, "w36", "" },
+ { SDLK_WORLD_37, "w37", "" },
+ { SDLK_WORLD_38, "w38", "" },
+ { SDLK_WORLD_39, "w39", "" },
+ { SDLK_WORLD_40, "w40", "" },
+ { SDLK_WORLD_41, "w41", "" },
+ { SDLK_WORLD_42, "w42", "" },
+ { SDLK_WORLD_43, "w43", "" },
+ { SDLK_WORLD_44, "w44", "" },
+ { SDLK_WORLD_45, "w45", "" },
+ { SDLK_WORLD_46, "w46", "" },
+ { SDLK_WORLD_47, "w47", "" },
+ { SDLK_WORLD_48, "w48", "" },
+ { SDLK_WORLD_49, "w49", "" },
+ { SDLK_WORLD_50, "w50", "" },
+ { SDLK_WORLD_51, "w51", "" },
+ { SDLK_WORLD_52, "w52", "" },
+ { SDLK_WORLD_53, "w53", "" },
+ { SDLK_WORLD_54, "w54", "" },
+ { SDLK_WORLD_55, "w55", "" },
+ { SDLK_WORLD_56, "w56", "" },
+ { SDLK_WORLD_57, "w57", "" },
+ { SDLK_WORLD_58, "w58", "" },
+ { SDLK_WORLD_59, "w59", "" },
+ { SDLK_WORLD_60, "w60", "" },
+ { SDLK_WORLD_61, "w61", "" },
+ { SDLK_WORLD_62, "w62", "" },
+ { SDLK_WORLD_63, "w63", "" },
+ { SDLK_WORLD_64, "w64", "" },
+ { SDLK_WORLD_65, "w65", "" },
+ { SDLK_WORLD_66, "w66", "" },
+ { SDLK_WORLD_67, "w67", "" },
+ { SDLK_WORLD_68, "w68", "" },
+ { SDLK_WORLD_69, "w69", "" },
+ { SDLK_WORLD_70, "w70", "" },
+ { SDLK_WORLD_71, "w71", "" },
+ { SDLK_WORLD_72, "w72", "" },
+ { SDLK_WORLD_73, "w73", "" },
+ { SDLK_WORLD_74, "w74", "" },
+ { SDLK_WORLD_75, "w75", "" },
+ { SDLK_WORLD_76, "w76", "" },
+ { SDLK_WORLD_77, "w77", "" },
+ { SDLK_WORLD_78, "w78", "" },
+ { SDLK_WORLD_79, "w79", "" },
+ { SDLK_WORLD_80, "w80", "" },
+ { SDLK_WORLD_81, "w81", "" },
+ { SDLK_WORLD_82, "w82", "" },
+ { SDLK_WORLD_83, "w83", "" },
+ { SDLK_WORLD_84, "w84", "" },
+ { SDLK_WORLD_85, "w85", "" },
+ { SDLK_WORLD_86, "w86", "" },
+ { SDLK_WORLD_87, "w87", "" },
+ { SDLK_WORLD_88, "w88", "" },
+ { SDLK_WORLD_89, "w89", "" },
+ { SDLK_WORLD_90, "w90", "" },
+ { SDLK_WORLD_91, "w91", "" },
+ { SDLK_WORLD_92, "w92", "" },
+ { SDLK_WORLD_93, "w93", "" },
+ { SDLK_WORLD_94, "w94", "" },
+ { SDLK_WORLD_95, "w95", "" },
+
+ /* Numeric keypad */
+ { SDLK_KP0, "KP0", "0" },
+ { SDLK_KP1, "KP1", "1" },
+ { SDLK_KP2, "KP2", "2" },
+ { SDLK_KP3, "KP3", "3" },
+ { SDLK_KP4, "KP4", "4" },
+ { SDLK_KP5, "KP5", "5" },
+ { SDLK_KP6, "KP6", "6" },
+ { SDLK_KP7, "KP7", "7" },
+ { SDLK_KP8, "KP8", "8" },
+ { SDLK_KP9, "KP9", "9" },
+ { SDLK_KP_PERIOD, "period", "." },
+ { SDLK_KP_DIVIDE, "KP_Divide", "/" },
+ { SDLK_KP_MULTIPLY, "KP_Multiply", "*" },
+ { SDLK_KP_MINUS, "KP_Minus", "-" },
+ { SDLK_KP_PLUS, "KP_Plus", "+" },
+ { SDLK_KP_ENTER, "KP_Enter", "\015" },
+ { SDLK_KP_EQUALS, "KP_Equals", "=" },
+
+ /* Arrows + Home/End pad */
+ { SDLK_UP, "Up", "Up" },
+ { SDLK_DOWN, "Down", "Down" },
+ { SDLK_RIGHT, "Right", "Right" },
+ { SDLK_LEFT, "Left", "Left" },
+ { SDLK_INSERT, "Insert", "Insert" },
+ { SDLK_HOME, "Home", "Home" },
+ { SDLK_END, "End", "End" },
+ { SDLK_PAGEUP, "Page_Up", "Page_Up" },
+ { SDLK_PAGEDOWN, "Page_Down", "Page_Down" },
+
+ /* Function keys */
+ { SDLK_F1, "F1", "F1" },
+ { SDLK_F2, "F2", "F2" },
+ { SDLK_F3, "F3", "F3" },
+ { SDLK_F4, "F4", "F4" },
+ { SDLK_F5, "F5", "F5" },
+ { SDLK_F6, "F6", "F6" },
+ { SDLK_F7, "F7", "F7" },
+ { SDLK_F8, "F8", "F8" },
+ { SDLK_F9, "F9", "F9" },
+ { SDLK_F10, "F10", "F10" },
+ { SDLK_F11, "F11", "F11" },
+ { SDLK_F12, "F12", "F12" },
+ { SDLK_F13, "F13", "F13" },
+ { SDLK_F14, "F14", "F14" },
+ { SDLK_F15, "F15", "F15" },
+
+ /* Key state modifier keys */
+ { SDLK_NUMLOCK, "Num_Lock", "Num_Lock" },
+ { SDLK_CAPSLOCK, "Caps_Lock", "Caps_Lock" },
+ { SDLK_SCROLLOCK, "Scroll_Lock", "Scroll_Lock" },
+ { SDLK_RSHIFT, "Shift_R", "Shift_R" },
+ { SDLK_LSHIFT, "Shift_L", "Shift_L" },
+ { SDLK_RCTRL, "Control_R", "Control_R" },
+ { SDLK_LCTRL, "Control_L", "Control_L" },
+ { SDLK_RALT, "Alt_R", "Alt_R" },
+ { SDLK_LALT, "Alt_L", "Alt_L" },
+ { SDLK_RMETA, "Meta_R", "Meta_R" },
+ { SDLK_LMETA, "Meta_L", "Meta_L" },
+ { SDLK_LSUPER, "Super_L", "Super_L" }, /* Left "Windows" key */
+ { SDLK_RSUPER, "Super_R", "Super_R" }, /* Right "Windows" key */
+ { SDLK_MODE, "Mode", "Mode" }, /* "Alt Gr" key */
+ { SDLK_COMPOSE, "Compose", "Compose" }, /* Multi-key compose key */
+
+ /* Miscellaneous function keys */
+ { SDLK_HELP, "Help", "Help" },
+ { SDLK_PRINT, "Print", "Print" },
+ { SDLK_SYSREQ, "SysReq", "SysReq" },
+ { SDLK_BREAK, "Break", "Break" },
+ { SDLK_MENU, "Menu", "Menu" },
+ { SDLK_POWER, "Power", "Power" }, /* Power Macintosh power key */
+ { SDLK_EURO, "Euro", "\200" }, /* Some european keyboards */
+ { SDLK_UNDO, "Undo", "Undo" } /* Atari keyboard has Undo */
+};
+
+#endif /* ECORE_SDL_KEYS_H__ */
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_evas \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_evas \
+-I$(top_builddir)/src/lib/ecore_input \
+@EFL_ECORE_SDL_BUILD@ \
+@SDL_CFLAGS@ \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@
+
+if BUILD_ECORE_SDL
+
+lib_LTLIBRARIES = libecore_sdl.la
+include_HEADERS = \
+Ecore_Sdl.h
+
+libecore_sdl_la_SOURCES = \
+ecore_sdl.c
+
+libecore_sdl_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+@SDL_LIBS@ @EVIL_LIBS@ @EINA_LIBS@
+
+libecore_sdl_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_sdl_release_info@
+
+endif
+
+EXTRA_DIST = Ecore_Sdl_Keys.h ecore_sdl_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <SDL/SDL.h>
+
+#include "Eina.h"
+#include "Ecore_Sdl.h"
+#include "Ecore_Input.h"
+#include "Ecore.h"
+#include "ecore_sdl_private.h"
+#include "ecore_private.h"
+#include "Ecore_Sdl_Keys.h"
+
+#include <eina_rbtree.h>
+
+int _ecore_sdl_log_dom = -1;
+
+typedef struct _Ecore_SDL_Pressed Ecore_SDL_Pressed;
+struct _Ecore_SDL_Pressed
+{
+ EINA_RBTREE;
+
+ SDLKey key;
+};
+
+EAPI int ECORE_SDL_EVENT_GOT_FOCUS = 0;
+EAPI int ECORE_SDL_EVENT_LOST_FOCUS = 0;
+EAPI int ECORE_SDL_EVENT_RESIZE = 0;
+EAPI int ECORE_SDL_EVENT_EXPOSE = 0;
+
+static int _ecore_sdl_init_count = 0;
+static Eina_Rbtree *repeat = NULL;
+
+static Eina_Rbtree_Direction
+_ecore_sdl_pressed_key(const Ecore_SDL_Pressed *left,
+ const Ecore_SDL_Pressed *right,
+ __UNUSED__ void *data)
+{
+ return left->key < right->key ? EINA_RBTREE_LEFT : EINA_RBTREE_RIGHT;
+}
+
+static int
+_ecore_sdl_pressed_node(const Ecore_SDL_Pressed *node,
+ const SDLKey *key,
+ __UNUSED__ int length,
+ __UNUSED__ void *data)
+{
+ return node->key - *key;
+}
+
+/**
+ * @defgroup Ecore_Sdl_Library_Group Framebuffer Library Functions
+ *
+ * Functions used to set up and shut down the Ecore_Framebuffer functions.
+ */
+
+/**
+ * Sets up the Ecore_Sdl library.
+ * @param name device target name
+ * @return @c 0 on failure. Otherwise, the number of times the library has
+ * been initialised without being shut down.
+ * @ingroup Ecore_SDL_Library_Group
+ */
+EAPI int
+ecore_sdl_init(const char *name __UNUSED__)
+{
+ if(++_ecore_sdl_init_count != 1)
+ return _ecore_sdl_init_count;
+ _ecore_sdl_log_dom = eina_log_domain_register("EcoreSdl", ECORE_SDL_DEFAULT_LOG_COLOR);
+ if(_ecore_sdl_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the Ecore SDL module.");
+ return --_ecore_sdl_init_count;
+ }
+ if (!ecore_event_init())
+ return --_ecore_sdl_init_count;
+
+ ECORE_SDL_EVENT_GOT_FOCUS = ecore_event_type_new();
+ ECORE_SDL_EVENT_LOST_FOCUS = ecore_event_type_new();
+ ECORE_SDL_EVENT_RESIZE = ecore_event_type_new();
+ ECORE_SDL_EVENT_EXPOSE = ecore_event_type_new();
+
+ SDL_EnableKeyRepeat(200, 100);
+
+ return _ecore_sdl_init_count;
+}
+
+/**
+ * Shuts down the Ecore_Sdl library.
+ * @return @c The number of times the system has been initialised without
+ * being shut down.
+ * @ingroup Ecore_SDL_Library_Group
+ */
+EAPI int
+ecore_sdl_shutdown(void)
+{
+ if (--_ecore_sdl_init_count != 0);
+ return _ecore_sdl_init_count;
+
+ ecore_event_shutdown();
+ eina_log_domain_unregister(_ecore_sdl_log_dom);
+ _ecore_sdl_log_dom = -1;
+ return _ecore_sdl_init_count;
+}
+
+static unsigned int
+_ecore_sdl_event_modifiers(int mod)
+{
+ unsigned int modifiers = 0;
+
+ if(mod & KMOD_LSHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if(mod & KMOD_RSHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if(mod & KMOD_LCTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if(mod & KMOD_RCTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if(mod & KMOD_LALT) modifiers |= ECORE_EVENT_MODIFIER_ALT;
+ if(mod & KMOD_RALT) modifiers |= ECORE_EVENT_MODIFIER_ALT;
+ if(mod & KMOD_NUM) modifiers |= ECORE_EVENT_LOCK_NUM;
+ if(mod & KMOD_CAPS) modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ return modifiers;
+}
+
+static Ecore_Event_Key*
+_ecore_sdl_event_key(SDL_Event *event, double time)
+{
+ Ecore_Event_Key *ev;
+ unsigned int i;
+
+ ev = malloc(sizeof(Ecore_Event_Key));
+ if (!ev) return NULL;
+
+ ev->timestamp = time;
+ ev->window = 0;
+ ev->modifiers = _ecore_sdl_event_modifiers(SDL_GetModState());
+ ev->key = NULL;
+ ev->compose = NULL;
+
+ for (i = 0; i < sizeof(keystable) / sizeof(struct _ecore_sdl_keys_s); ++i)
+ if (keystable[i].code == event->key.keysym.sym)
+ {
+ ev->keyname = keystable[i].name;
+ ev->string = keystable[i].compose;
+
+ return ev;
+ }
+
+ free(ev);
+ return NULL;
+}
+
+EAPI void
+ecore_sdl_feed_events(void)
+{
+ SDL_Event event;
+ unsigned int time;
+
+ while(SDL_PollEvent(&event))
+ {
+ time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff);
+ switch(event.type)
+ {
+ case SDL_MOUSEMOTION:
+ {
+ Ecore_Event_Mouse_Move *ev;
+
+ ev = malloc(sizeof(Ecore_Event_Mouse_Move));
+ if (!ev) return ;
+
+ ev->timestamp = time;
+ ev->window = 0;
+ ev->modifiers = 0; /* FIXME: keep modifier around. */
+ ev->x = event.motion.x;
+ ev->y = event.motion.y;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
+ break;
+ }
+ case SDL_MOUSEBUTTONDOWN:
+ {
+ if (event.button.button == SDL_BUTTON_WHEELUP ||
+ event.button.button == SDL_BUTTON_WHEELDOWN)
+ {
+ Ecore_Event_Mouse_Wheel *ev;
+
+ ev = malloc(sizeof(Ecore_Event_Mouse_Wheel));
+ if (!ev) return ;
+
+ ev->timestamp = time;
+ ev->window = 0;
+ ev->modifiers = 0; /* FIXME: keep modifier around. */
+ ev->direction = 0;
+ ev->z = event.button.button == SDL_BUTTON_WHEELDOWN ? -1 : 1;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
+ }
+ else
+ {
+ Ecore_Event_Mouse_Button *ev;
+
+ ev = malloc(sizeof(Ecore_Event_Mouse_Button));
+ if (!ev) return ;
+
+ ev->timestamp = time;
+ ev->window = 0;
+ ev->modifiers = 0; /* FIXME: keep modifier around. */
+ ev->buttons = event.button.button;
+ ev->double_click = 0;
+ ev->triple_click = 0;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
+ }
+ break;
+ }
+ case SDL_MOUSEBUTTONUP:
+ {
+ Ecore_Event_Mouse_Button *ev;
+
+ ev = malloc(sizeof(Ecore_Event_Mouse_Button));
+ if (!ev) return ;
+ ev->timestamp = time;
+ ev->window = 0;
+ ev->modifiers = 0; /* FIXME: keep modifier around. */
+ ev->buttons = event.button.button;
+ ev->double_click = 0;
+ ev->triple_click = 0;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
+ break;
+ }
+ case SDL_VIDEORESIZE:
+ {
+ Ecore_Sdl_Event_Video_Resize *ev;
+
+ ev = malloc(sizeof (Ecore_Sdl_Event_Video_Resize));
+ ev->w = event.resize.w;
+ ev->h = event.resize.h;
+
+ ecore_event_add(ECORE_SDL_EVENT_RESIZE, ev, NULL, NULL);
+ break;
+ }
+ case SDL_VIDEOEXPOSE:
+ ecore_event_add(ECORE_SDL_EVENT_EXPOSE, NULL, NULL, NULL);
+ break;
+ case SDL_QUIT:
+ ecore_main_loop_quit();
+ break;
+
+ case SDL_KEYDOWN:
+ {
+ Ecore_SDL_Pressed *entry;
+ Ecore_Event_Key *ev;
+
+ entry = (Ecore_SDL_Pressed*) eina_rbtree_inline_lookup(repeat, &event.key.keysym.sym, sizeof (event.key.keysym.sym),
+ EINA_RBTREE_CMP_KEY_CB(_ecore_sdl_pressed_node), NULL);
+ if (entry)
+ {
+ ev = _ecore_sdl_event_key(&event, time);
+ if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
+ }
+
+ ev = _ecore_sdl_event_key(&event, time);
+ if (ev) ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
+
+ if (!entry)
+ {
+ entry = malloc(sizeof (Ecore_SDL_Pressed));
+ if (!entry) break;
+
+ entry->key = event.key.keysym.sym;
+
+ repeat = eina_rbtree_inline_insert(repeat, EINA_RBTREE_GET(entry),
+ EINA_RBTREE_CMP_NODE_CB(_ecore_sdl_pressed_key), NULL);
+ }
+ break;
+ }
+ case SDL_KEYUP:
+ {
+ Ecore_Event_Key *ev;
+ Ecore_SDL_Pressed *entry;
+
+ entry = (Ecore_SDL_Pressed*) eina_rbtree_inline_lookup(repeat, &event.key.keysym.sym, sizeof (event.key.keysym.sym),
+ EINA_RBTREE_CMP_KEY_CB(_ecore_sdl_pressed_node), NULL);
+ if (entry)
+ {
+ repeat = eina_rbtree_inline_remove(repeat, EINA_RBTREE_GET(entry),
+ EINA_RBTREE_CMP_NODE_CB(_ecore_sdl_pressed_key), NULL);
+ free(entry);
+ }
+
+ ev = _ecore_sdl_event_key(&event, time);
+ if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
+ break;
+ }
+ case SDL_ACTIVEEVENT:
+ /* FIXME: Focus gain. */
+ break;
+ case SDL_SYSWMEVENT:
+ case SDL_USEREVENT:
+ case SDL_JOYAXISMOTION:
+ case SDL_JOYBALLMOTION:
+ case SDL_JOYHATMOTION:
+ case SDL_JOYBUTTONDOWN:
+ case SDL_JOYBUTTONUP:
+ default:
+ break;
+ }
+ }
+}
--- /dev/null
+#ifndef _ECORE_SDL_PRIVATE_H
+# define _ECORE_SDL_PRIVATE_H
+
+extern int _ecore_sdl_log_dom;
+
+# ifdef ECORE_SDL_DEFAULT_LOG_COLOR
+# undef ECORE_SDL_DEFAULT_LOG_COLOR
+# endif
+# define ECORE_SDL_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+# ifdef ERR
+# undef ERR
+# endif
+# define ERR(...) EINA_LOG_DOM_ERR(_ecore_sdl_log_dom, __VA_ARGS__)
+
+# ifdef DBG
+# undef DBG
+# endif
+# define DBG(...) EINA_LOG_DOM_DBG(_ecore_sdl_log_dom, __VA_ARGS__)
+
+# ifdef INF
+# undef INF
+# endif
+# define INF(...) EINA_LOG_DOM_INFO(_ecore_sdl_log_dom, __VA_ARGS__)
+
+# ifdef WRN
+# undef WRN
+# endif
+# define WRN(...) EINA_LOG_DOM_WARN(_ecore_sdl_log_dom, __VA_ARGS__)
+
+# ifdef CRIT
+# undef CRIT
+# endif
+# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_sdl_log_dom, __VA_ARGS__)
+
+#endif
--- /dev/null
+.libs
+.deps
+Makefile
+Makefile.in
+*.lo
+*.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef __ECORE_WIN32_H__
+#define __ECORE_WIN32_H__
+
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_WIN32_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_WIN32_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct _Ecore_Win32_Window Ecore_Win32_Window;
+typedef void Ecore_Win32_Cursor;
+
+/* Window state */
+
+typedef enum
+{
+ /* The window is iconified. */
+ ECORE_WIN32_WINDOW_STATE_ICONIFIED,
+ /* The window is a modal dialog box. */
+ ECORE_WIN32_WINDOW_STATE_MODAL,
+ /* The window manager should keep the window's position fixed
+ * even if the virtual desktop scrolls. */
+ ECORE_WIN32_WINDOW_STATE_STICKY,
+ /* The window has the maximum vertical size. */
+ ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT,
+ /* The window has the maximum horizontal size. */
+ ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ,
+ /* The window has the maximum horizontal and vertical size. */
+ ECORE_WIN32_WINDOW_STATE_MAXIMIZED,
+ /* The window is shaded. */
+ ECORE_WIN32_WINDOW_STATE_SHADED,
+ /* The window is invisible (i.e. minimized/iconified) */
+ ECORE_WIN32_WINDOW_STATE_HIDDEN,
+ /* The window should fill the entire screen and have no
+ * window border/decorations */
+ ECORE_WIN32_WINDOW_STATE_FULLSCREEN,
+ /* The following are not documented because they are not
+ * intended for use in applications. */
+ ECORE_WIN32_WINDOW_STATE_ABOVE,
+ ECORE_WIN32_WINDOW_STATE_BELOW,
+ /* FIXME: Documentation */
+ ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION,
+ /* Unknown state */
+ ECORE_WIN32_WINDOW_STATE_UNKNOWN
+} Ecore_Win32_Window_State;
+
+/* Window type */
+
+typedef enum
+{
+ /* Desktop feature*/
+ ECORE_WIN32_WINDOW_TYPE_DESKTOP,
+ /* Dock window (should be on top of other windows */
+ ECORE_WIN32_WINDOW_TYPE_DOCK,
+ /* Toolbar window */
+ ECORE_WIN32_WINDOW_TYPE_TOOLBAR,
+ /* Menu window */
+ ECORE_WIN32_WINDOW_TYPE_MENU,
+ /* Small persistent utility window, such as a palette or toolbox */
+ ECORE_WIN32_WINDOW_TYPE_UTILITY,
+ /* Splash screen window displayed as an application is starting up */
+ ECORE_WIN32_WINDOW_TYPE_SPLASH,
+ /* Dialog window */
+ ECORE_WIN32_WINDOW_TYPE_DIALOG,
+ /* Normal top-level window */
+ ECORE_WIN32_WINDOW_TYPE_NORMAL,
+ /* Unknown type */
+ ECORE_WIN32_WINDOW_TYPE_UNKNOWN
+} Ecore_Win32_Window_Type;
+
+/*cursor shapes */
+
+typedef enum
+{
+ ECORE_WIN32_CURSOR_SHAPE_APP_STARTING, /* Standard arrow and small hourglass */
+ ECORE_WIN32_CURSOR_SHAPE_ARROW, /* Standard arrow */
+ ECORE_WIN32_CURSOR_SHAPE_CROSS, /* Crosshair */
+ ECORE_WIN32_CURSOR_SHAPE_HAND, /* Hand */
+ ECORE_WIN32_CURSOR_SHAPE_HELP, /* Arrow and question mark */
+ ECORE_WIN32_CURSOR_SHAPE_I_BEAM, /* I-beam */
+ ECORE_WIN32_CURSOR_SHAPE_NO, /* Slashed circle */
+ ECORE_WIN32_CURSOR_SHAPE_SIZE_ALL, /* Four-pointed arrow pointing north, south, east, and west */
+ ECORE_WIN32_CURSOR_SHAPE_SIZE_NESW, /* Double-pointed arrow pointing northeast and southwest */
+ ECORE_WIN32_CURSOR_SHAPE_SIZE_NS, /* Double-pointed arrow pointing north and south */
+ ECORE_WIN32_CURSOR_SHAPE_SIZE_NWSE, /* Double-pointed arrow pointing northwest and southeast */
+ ECORE_WIN32_CURSOR_SHAPE_SIZE_WE, /* Double-pointed arrow pointing west and east */
+ ECORE_WIN32_CURSOR_SHAPE_UP_ARROW, /* Vertical arrow */
+ ECORE_WIN32_CURSOR_SHAPE_WAIT /* Hourglass */
+} Ecore_Win32_Cursor_Shape;
+
+/* Events */
+
+typedef struct _Ecore_Win32_Event_Mouse_In Ecore_Win32_Event_Mouse_In;
+typedef struct _Ecore_Win32_Event_Mouse_Out Ecore_Win32_Event_Mouse_Out;
+typedef struct _Ecore_Win32_Event_Window_Focus_In Ecore_Win32_Event_Window_Focus_In;
+typedef struct _Ecore_Win32_Event_Window_Focus_Out Ecore_Win32_Event_Window_Focus_Out;
+typedef struct _Ecore_Win32_Event_Window_Damage Ecore_Win32_Event_Window_Damage;
+typedef struct _Ecore_Win32_Event_Window_Create Ecore_Win32_Event_Window_Create;
+typedef struct _Ecore_Win32_Event_Window_Destroy Ecore_Win32_Event_Window_Destroy;
+typedef struct _Ecore_Win32_Event_Window_Hide Ecore_Win32_Event_Window_Hide;
+typedef struct _Ecore_Win32_Event_Window_Show Ecore_Win32_Event_Window_Show;
+typedef struct _Ecore_Win32_Event_Window_Configure Ecore_Win32_Event_Window_Configure;
+typedef struct _Ecore_Win32_Event_Window_Resize Ecore_Win32_Event_Window_Resize;
+typedef struct _Ecore_Win32_Event_Window_Delete_Request Ecore_Win32_Event_Window_Delete_Request;
+
+struct _Ecore_Win32_Event_Mouse_In
+{
+ Ecore_Win32_Window *window;
+ int x;
+ int y;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Mouse_Out
+{
+ Ecore_Win32_Window *window;
+ int x;
+ int y;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Focus_In
+{
+ Ecore_Win32_Window *window;
+ long long time;
+};
+
+struct _Ecore_Win32_Event_Window_Focus_Out
+{
+ Ecore_Win32_Window *window;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Damage
+{
+ Ecore_Win32_Window *window;
+ int x;
+ int y;
+ int width;
+ int height;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Create
+{
+ Ecore_Win32_Window *window;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Destroy
+{
+ Ecore_Win32_Window *window;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Hide
+{
+ Ecore_Win32_Window *window;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Show
+{
+ Ecore_Win32_Window *window;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Configure
+{
+ Ecore_Win32_Window *window;
+ Ecore_Win32_Window *abovewin;
+ int x;
+ int y;
+ int width;
+ int height;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Resize
+{
+ Ecore_Win32_Window *window;
+ int width;
+ int height;
+ long time;
+};
+
+struct _Ecore_Win32_Event_Window_Delete_Request
+{
+ Ecore_Win32_Window *window;
+ long time;
+};
+
+#define ECORE_WIN32_DND_EVENT_DRAG_ENTER 1
+#define ECORE_WIN32_DND_EVENT_DRAG_OVER 2
+#define ECORE_WIN32_DND_EVENT_DRAG_LEAVE 3
+#define ECORE_WIN32_DND_EVENT_DROP 4
+
+
+typedef int (*Ecore_Win32_Dnd_DropTarget_Callback)(void *window, int event, int pt_x, int pt_y, void *data, int size);
+
+EAPI extern int ECORE_WIN32_EVENT_MOUSE_IN;
+EAPI extern int ECORE_WIN32_EVENT_MOUSE_OUT;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_DAMAGE;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_CREATE;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_DESTROY;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_HIDE;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_SHOW;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_CONFIGURE;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_RESIZE;
+EAPI extern int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST;
+
+
+/* Core */
+
+EAPI int ecore_win32_init();
+EAPI int ecore_win32_shutdown();
+EAPI int ecore_win32_screen_depth_get();
+EAPI long ecore_win32_current_time_get(void);
+EAPI void ecore_win32_message_loop_begin (void);
+
+/* Window */
+
+EAPI Ecore_Win32_Window *ecore_win32_window_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+EAPI Ecore_Win32_Window *ecore_win32_window_override_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI void ecore_win32_window_free(Ecore_Win32_Window *window);
+
+EAPI void *ecore_win32_window_hwnd_get(Ecore_Win32_Window *window);
+
+EAPI void ecore_win32_window_move(Ecore_Win32_Window *window,
+ int x,
+ int y);
+
+EAPI void ecore_win32_window_resize(Ecore_Win32_Window *window,
+ int width,
+ int height);
+
+EAPI void ecore_win32_window_move_resize(Ecore_Win32_Window *window,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI void ecore_win32_window_geometry_get(Ecore_Win32_Window *window,
+ int *x,
+ int *y,
+ int *width,
+ int *height);
+
+EAPI void ecore_win32_window_size_get(Ecore_Win32_Window *window,
+ int *width,
+ int *height);
+
+EAPI void ecore_win32_window_size_min_set(Ecore_Win32_Window *window,
+ unsigned int min_width,
+ unsigned int min_height);
+
+EAPI void ecore_win32_window_size_min_get(Ecore_Win32_Window *window,
+ unsigned int *min_width,
+ unsigned int *min_height);
+
+EAPI void ecore_win32_window_size_max_set(Ecore_Win32_Window *window,
+ unsigned int max_width,
+ unsigned int max_height);
+
+EAPI void ecore_win32_window_size_max_get(Ecore_Win32_Window *window,
+ unsigned int *max_width,
+ unsigned int *max_height);
+
+EAPI void ecore_win32_window_size_base_set(Ecore_Win32_Window *window,
+ unsigned int base_width,
+ unsigned int base_height);
+
+EAPI void ecore_win32_window_size_base_get(Ecore_Win32_Window *window,
+ unsigned int *base_width,
+ unsigned int *base_height);
+
+EAPI void ecore_win32_window_size_step_set(Ecore_Win32_Window *window,
+ unsigned int step_width,
+ unsigned int step_height);
+
+EAPI void ecore_win32_window_size_step_get(Ecore_Win32_Window *window,
+ unsigned int *step_width,
+ unsigned int *step_height);
+
+EAPI void ecore_win32_window_show(Ecore_Win32_Window *window);
+
+EAPI void ecore_win32_window_hide(Ecore_Win32_Window *window);
+
+EAPI void ecore_win32_window_raise(Ecore_Win32_Window *window);
+
+EAPI void ecore_win32_window_lower(Ecore_Win32_Window *window);
+
+EAPI void ecore_win32_window_title_set(Ecore_Win32_Window *window,
+ const char *title);
+
+EAPI void ecore_win32_window_focus_set(Ecore_Win32_Window *window);
+
+EAPI void ecore_win32_window_iconified_set(Ecore_Win32_Window *window,
+ int on);
+
+EAPI void ecore_win32_window_borderless_set(Ecore_Win32_Window *window,
+ int on);
+
+EAPI void ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window,
+ int on);
+
+EAPI void ecore_win32_window_shape_set(Ecore_Win32_Window *window,
+ unsigned short width,
+ unsigned short height,
+ unsigned char *mask);
+
+EAPI void ecore_win32_window_cursor_set(Ecore_Win32_Window *window,
+ Ecore_Win32_Cursor *cursor);
+
+EAPI void ecore_win32_window_state_set(Ecore_Win32_Window *window,
+ Ecore_Win32_Window_State *state,
+ unsigned int num);
+
+EAPI void ecore_win32_window_state_request_send(Ecore_Win32_Window *window,
+ Ecore_Win32_Window_State state,
+ unsigned int set);
+
+EAPI void ecore_win32_window_type_set(Ecore_Win32_Window *window,
+ Ecore_Win32_Window_Type type);
+
+/* Cursor */
+
+EAPI Ecore_Win32_Cursor *ecore_win32_cursor_new(const void *pixels_and,
+ const void *pixels_xor,
+ int width,
+ int height,
+ int hot_x,
+ int hot_y);
+
+EAPI void ecore_win32_cursor_free(Ecore_Win32_Cursor *cursor);
+
+EAPI Ecore_Win32_Cursor *ecore_win32_cursor_shape_get(Ecore_Win32_Cursor_Shape shape);
+
+EAPI int ecore_win32_cursor_size_get(void);
+
+
+
+/* Drag and drop */
+EAPI int ecore_win32_dnd_init();
+EAPI int ecore_win32_dnd_shutdown();
+EAPI int ecore_win32_dnd_begin(const char *data,
+ int size);
+EAPI int ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window,
+ Ecore_Win32_Dnd_DropTarget_Callback callback);
+EAPI void ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __ECORE_WIN32_H__ */
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_input \
+@EFL_ECORE_WIN32_BUILD@ \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@ \
+@WIN32_CPPFLAGS@
+
+
+if BUILD_ECORE_WIN32
+
+lib_LTLIBRARIES = libecore_win32.la
+
+include_HEADERS = \
+Ecore_Win32.h
+
+libecore_win32_la_SOURCES = \
+ecore_win32.c \
+ecore_win32_cursor.c \
+ecore_win32_dnd.c \
+ecore_win32_dnd_enumformatetc.cpp \
+ecore_win32_dnd_data_object.cpp \
+ecore_win32_dnd_drop_source.cpp \
+ecore_win32_dnd_drop_target.cpp \
+ecore_win32_event.c \
+ecore_win32_window.c
+
+libecore_win32_la_LIBADD = \
+@ecore_win32_libs@ \
+@WIN32_LIBS@ \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+@EVAS_LIBS@ \
+@EINA_LIBS@
+
+libecore_win32_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_win32_release_info@
+
+endif
+
+EXTRA_DIST = \
+ecore_win32_private.h \
+ecore_win32_dnd_enumformatetc.h \
+ecore_win32_dnd_data_object.h \
+ecore_win32_dnd_drop_source.h \
+ecore_win32_dnd_drop_target.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h> /* for printf */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <windowsx.h>
+
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
+#include "Ecore_Win32.h"
+#include "ecore_win32_private.h"
+
+
+/* OLE IID for Drag'n Drop */
+
+# define INITGUID
+# include <basetyps.h>
+DEFINE_OLEGUID(IID_IEnumFORMATETC, 0x00000103L, 0, 0);
+DEFINE_OLEGUID(IID_IDataObject, 0x0000010EL, 0, 0);
+DEFINE_OLEGUID(IID_IDropSource, 0x00000121L, 0, 0);
+DEFINE_OLEGUID(IID_IDropTarget, 0x00000122L, 0, 0);
+DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0);
+
+
+/***** Global declarations *****/
+
+HINSTANCE _ecore_win32_instance = NULL;
+double _ecore_win32_double_click_time = 0.25;
+long _ecore_win32_event_last_time = 0;
+Ecore_Win32_Window *_ecore_win32_event_last_window = NULL;
+int _ecore_win32_log_dom_global = -1;
+
+int ECORE_WIN32_EVENT_MOUSE_IN = 0;
+int ECORE_WIN32_EVENT_MOUSE_OUT = 0;
+int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN = 0;
+int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT = 0;
+int ECORE_WIN32_EVENT_WINDOW_DAMAGE = 0;
+int ECORE_WIN32_EVENT_WINDOW_CREATE = 0;
+int ECORE_WIN32_EVENT_WINDOW_DESTROY = 0;
+int ECORE_WIN32_EVENT_WINDOW_SHOW = 0;
+int ECORE_WIN32_EVENT_WINDOW_HIDE = 0;
+int ECORE_WIN32_EVENT_WINDOW_CONFIGURE = 0;
+int ECORE_WIN32_EVENT_WINDOW_RESIZE = 0;
+int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST = 0;
+
+
+/***** Private declarations *****/
+
+static int _ecore_win32_init_count = 0;
+
+LRESULT CALLBACK _ecore_win32_window_procedure(HWND window,
+ UINT message,
+ WPARAM window_param,
+ LPARAM data_param);
+
+static void _ecore_win32_error_print_cb(const Eina_Log_Domain *d,
+ Eina_Log_Level level,
+ const char *file,
+ const char *fnc,
+ int line,
+ const char *fmt,
+ void *data,
+ va_list args);
+
+
+/***** API *****/
+
+
+int
+ecore_win32_init()
+{
+ WNDCLASS wc;
+
+ if (++_ecore_win32_init_count != 1)
+ return _ecore_win32_init_count;
+
+ if (!eina_init())
+ return --_ecore_win32_init_count;
+
+ eina_log_print_cb_set(_ecore_win32_error_print_cb, NULL);
+ _ecore_win32_log_dom_global = eina_log_domain_register("ecore_win32", ECORE_WIN32_DEFAULT_LOG_COLOR);
+ if (_ecore_win32_log_dom_global < 0)
+ {
+ EINA_LOG_ERR("Ecore_Win32: Could not register log domain");
+ goto shutdown_eina;
+ }
+
+ if (!ecore_event_init())
+ {
+ ERR("Ecore_Win32: Could not init ecore_event");
+ goto unregister_log_domain;
+ }
+
+ _ecore_win32_instance = GetModuleHandle(NULL);
+ if (!_ecore_win32_instance)
+ {
+ ERR("GetModuleHandle() failed");
+ goto shutdown_ecore_event;
+ }
+
+ memset (&wc, 0, sizeof (WNDCLASS));
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = _ecore_win32_window_procedure;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = _ecore_win32_instance;
+ wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = ECORE_WIN32_WINDOW_CLASS;
+
+ if(!RegisterClass(&wc))
+ {
+ ERR("RegisterClass() failed");
+ goto free_library;
+ }
+
+ if (!ecore_win32_dnd_init())
+ {
+ ERR("ecore_win32_dnd_init() failed");
+ goto unregister_class;
+ }
+
+ if (!ECORE_WIN32_EVENT_MOUSE_IN)
+ {
+ ECORE_WIN32_EVENT_MOUSE_IN = ecore_event_type_new();
+ ECORE_WIN32_EVENT_MOUSE_OUT = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_CREATE = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_DESTROY = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_SHOW = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_HIDE = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_RESIZE = ecore_event_type_new();
+ ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
+ }
+
+ return _ecore_win32_init_count;
+
+ unregister_class:
+ UnregisterClass(ECORE_WIN32_WINDOW_CLASS, _ecore_win32_instance);
+ free_library:
+ FreeLibrary(_ecore_win32_instance);
+ shutdown_ecore_event:
+ ecore_event_shutdown();
+ unregister_log_domain:
+ eina_log_domain_unregister(_ecore_win32_log_dom_global);
+ shutdown_eina:
+ eina_shutdown();
+
+ return --_ecore_win32_init_count;
+}
+
+int
+ecore_win32_shutdown()
+{
+ if (--_ecore_win32_init_count != 0)
+ return _ecore_win32_init_count;
+
+ ecore_win32_dnd_shutdown();
+
+ if (!UnregisterClass(ECORE_WIN32_WINDOW_CLASS, _ecore_win32_instance))
+ INF("UnregisterClass() failed");
+
+ if (!FreeLibrary(_ecore_win32_instance))
+ INF("FreeLibrary() failed");
+
+ _ecore_win32_instance = NULL;
+
+ ecore_event_shutdown();
+ eina_log_domain_unregister(_ecore_win32_log_dom_global);
+ _ecore_win32_log_dom_global = -1;
+ eina_shutdown();
+
+ return _ecore_win32_init_count;
+}
+
+int
+ecore_win32_screen_depth_get()
+{
+ HDC dc;
+ int depth;
+
+ INF("getting screen depth");
+
+ dc = GetDC(NULL);
+ if (!dc)
+ {
+ ERR("GetDC() failed");
+ return 0;
+ }
+
+ depth = GetDeviceCaps(dc, BITSPIXEL);
+ if (!ReleaseDC(NULL, dc))
+ {
+ ERR("ReleaseDC() failed (device context not released)");
+ }
+
+ return depth;
+}
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ */
+void
+ecore_win32_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_win32_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_win32_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ */
+double
+ecore_win32_double_click_time_get(void)
+{
+ return _ecore_win32_double_click_time;
+}
+
+/**
+ * Return the last event time
+ */
+long
+ecore_win32_current_time_get(void)
+{
+ return _ecore_win32_event_last_time;
+}
+
+
+/***** Private functions definitions *****/
+
+
+LRESULT CALLBACK
+_ecore_win32_window_procedure(HWND window,
+ UINT message,
+ WPARAM window_param,
+ LPARAM data_param)
+{
+ Ecore_Win32_Callback_Data *data;
+ POINTS pt;
+ DWORD coord;
+
+ data = (Ecore_Win32_Callback_Data *)malloc(sizeof(Ecore_Win32_Callback_Data));
+ if (!data) return DefWindowProc(window, message, window_param, data_param);
+
+ data->window = window;
+ data->message = message;
+ data->window_param = window_param;
+ data->data_param = data_param;
+ data->time = GetMessageTime();
+ coord = GetMessagePos();
+ pt = MAKEPOINTS(coord);
+ data->x = pt.x;
+ data->y = pt.y;
+
+ switch (data->message)
+ {
+ /* Keyboard input notifications */
+ case WM_KEYDOWN:
+ _ecore_win32_event_handle_key_press(data, 1);
+ return 0;
+ case WM_CHAR:
+ _ecore_win32_event_handle_key_press(data, 0);
+ return 0;
+ case WM_KEYUP:
+ _ecore_win32_event_handle_key_release(data, 1);
+ return 0;
+ case WM_SETFOCUS:
+ _ecore_win32_event_handle_focus_in(data);
+ return 0;
+ case WM_KILLFOCUS:
+ _ecore_win32_event_handle_focus_out(data);
+ return 0;
+ /* Mouse input notifications */
+ case WM_LBUTTONDOWN:
+ _ecore_win32_event_handle_button_press(data, 1);
+ return 0;
+ case WM_MBUTTONDOWN:
+ _ecore_win32_event_handle_button_press(data, 2);
+ return 0;
+ case WM_RBUTTONDOWN:
+ _ecore_win32_event_handle_button_press(data, 3);
+ return 0;
+ case WM_LBUTTONUP:
+ _ecore_win32_event_handle_button_release(data, 1);
+ return 0;
+ case WM_MBUTTONUP:
+ _ecore_win32_event_handle_button_release(data, 2);
+ return 0;
+ case WM_RBUTTONUP:
+ _ecore_win32_event_handle_button_release(data, 3);
+ return 0;
+ case WM_MOUSEMOVE:
+ {
+ RECT rect;
+ struct _Ecore_Win32_Window *w = NULL;
+
+ w = (struct _Ecore_Win32_Window *)GetWindowLong(window, GWL_USERDATA);
+
+ if (GetClientRect(window, &rect))
+ {
+ POINT pt;
+
+ INF("mouse in window");
+
+ pt.x = GET_X_LPARAM(data_param);
+ pt.y = GET_Y_LPARAM(data_param);
+ if (!PtInRect(&rect, pt))
+ {
+ if (w->pointer_is_in)
+ {
+ w->pointer_is_in = 0;
+ _ecore_win32_event_handle_leave_notify(data);
+ }
+ }
+ else
+ {
+ if (!w->pointer_is_in)
+ {
+ w->pointer_is_in = 1;
+ _ecore_win32_event_handle_enter_notify(data);
+ }
+ }
+ }
+ else
+ {
+ ERR("GetClientRect() failed");
+ }
+ _ecore_win32_event_handle_motion_notify(data);
+
+ return 0;
+ }
+ case WM_MOUSEWHEEL:
+ _ecore_win32_event_handle_button_press(data, 4);
+ return 0;
+ /* Window notifications */
+ case WM_CREATE:
+ _ecore_win32_event_handle_create_notify(data);
+ return 0;
+ case WM_DESTROY:
+ _ecore_win32_event_handle_destroy_notify(data);
+ return 0;
+ case WM_SHOWWINDOW:
+ if ((data->data_param == SW_OTHERUNZOOM) ||
+ (data->data_param == SW_OTHERUNZOOM))
+ return 0;
+
+ if (data->window_param)
+ _ecore_win32_event_handle_map_notify(data);
+ else
+ _ecore_win32_event_handle_unmap_notify(data);
+
+ return 0;
+ case WM_CLOSE:
+ _ecore_win32_event_handle_delete_request(data);
+ return 0;
+ case WM_MOVING:
+ printf (" * ecore message : moving\n");
+ return TRUE;
+ case WM_MOVE:
+ printf (" * ecore message : moved\n");
+ return 0;
+ case WM_SIZING:
+ printf (" * ecore message : sizing\n");
+ _ecore_win32_event_handle_resize(data);
+ _ecore_win32_event_handle_configure_notify(data);
+ return TRUE;
+ case WM_SIZE:
+ printf (" * ecore message : sized\n");
+ return 0;
+/* case WM_WINDOWPOSCHANGING: */
+/* { */
+/* RECT rect; */
+/* GetClientRect(window, &rect); */
+/* printf (" *** ecore message : WINDOWPOSCHANGING %ld %ld\n", */
+/* rect.right - rect.left, rect.bottom - rect.top); */
+/* } */
+/* _ecore_win32_event_handle_configure_notify(data); */
+/* return 0; */
+ case WM_WINDOWPOSCHANGED:
+ _ecore_win32_event_handle_configure_notify(data);
+ return 0;
+ case WM_ENTERSIZEMOVE :
+ printf (" * ecore message : WM_ENTERSIZEMOVE \n");
+ return 0;
+ case WM_EXITSIZEMOVE:
+ printf (" * ecore message : WM_EXITSIZEMOVE\n");
+ return 0;
+ /* GDI notifications */
+ case WM_PAINT:
+ {
+ RECT rect;
+
+ if (GetUpdateRect(window, &rect, FALSE))
+ {
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ hdc = BeginPaint(window, &ps);
+ data->update = rect;
+ _ecore_win32_event_handle_expose(data);
+ EndPaint(window, &ps);
+ }
+ return 0;
+ }
+ case WM_SETREDRAW:
+ printf (" * ecore message : WM_SETREDRAW\n");
+ return 0;
+ case WM_SYNCPAINT:
+ printf (" * ecore message : WM_SYNCPAINT\n");
+ return 0;
+ default:
+ return DefWindowProc(window, message, window_param, data_param);
+ }
+}
+
+static void
+_ecore_win32_error_print_cb(const Eina_Log_Domain *d __UNUSED__,
+ Eina_Log_Level level __UNUSED__,
+ const char *file __UNUSED__,
+ const char *fnc,
+ int line,
+ const char *fmt,
+ void *data __UNUSED__,
+ va_list args)
+{
+ fprintf(stderr, "[%s:%d] ", fnc, line);
+ vfprintf(stderr, fmt, args);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <Eina.h>
+
+#include "Ecore_Win32.h"
+#include "ecore_win32_private.h"
+
+
+/***** API *****/
+
+Ecore_Win32_Cursor *
+ecore_win32_cursor_new(const void *pixels_and,
+ const void *pixels_xor,
+ int width,
+ int height,
+ int hot_x,
+ int hot_y)
+{
+ Ecore_Win32_Cursor *cursor = NULL;
+ int cursor_width;
+ int cursor_height;
+
+ INF("creating cursor");
+
+ cursor_width = GetSystemMetrics(SM_CXCURSOR);
+ cursor_height = GetSystemMetrics(SM_CYCURSOR);
+
+ if ((cursor_width != width) ||
+ (cursor_height != height))
+ return NULL;
+
+ if (!(cursor = CreateCursor(_ecore_win32_instance,
+ hot_x, hot_y,
+ width, height,
+ pixels_and,
+ pixels_xor)))
+ return NULL;
+
+ return cursor;
+}
+
+void
+ecore_win32_cursor_free(Ecore_Win32_Cursor *cursor)
+{
+ INF("destroying cursor");
+
+ DestroyCursor(cursor);
+}
+
+Ecore_Win32_Cursor *
+ecore_win32_cursor_shape_get(Ecore_Win32_Cursor_Shape shape)
+{
+ Ecore_Win32_Cursor *cursor = NULL;
+ const char *cursor_name;
+
+ INF("geting shape cursor");
+
+ switch (shape)
+ {
+ case ECORE_WIN32_CURSOR_SHAPE_APP_STARTING:
+ cursor_name = IDC_APPSTARTING;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_ARROW:
+ cursor_name = IDC_ARROW;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_CROSS:
+ cursor_name = IDC_CROSS;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_HAND:
+ cursor_name = IDC_HAND;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_HELP:
+ cursor_name = IDC_HELP;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_I_BEAM:
+ cursor_name = IDC_IBEAM;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_NO:
+ cursor_name = IDC_NO;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_SIZE_ALL:
+ cursor_name = IDC_SIZEALL;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_SIZE_NESW:
+ cursor_name = IDC_SIZENESW;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_SIZE_NS:
+ cursor_name = IDC_SIZENS;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_SIZE_NWSE:
+ cursor_name = IDC_SIZENWSE;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_SIZE_WE:
+ cursor_name = IDC_SIZEWE;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_UP_ARROW:
+ cursor_name = IDC_UPARROW;
+ break;
+ case ECORE_WIN32_CURSOR_SHAPE_WAIT:
+ cursor_name = IDC_WAIT;
+ break;
+ default:
+ return NULL;
+ }
+
+ if (!(cursor = LoadCursor(NULL, cursor_name)))
+ return NULL;
+
+ return cursor;
+}
+
+int
+ecore_win32_cursor_size_get(void)
+{
+ int width;
+ int height;
+
+ INF("geting size cursor");
+
+ width = GetSystemMetrics(SM_CXCURSOR);
+ height = GetSystemMetrics(SM_CYCURSOR);
+ return (width > height) ? width : height;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <windows.h>
+
+#include "Ecore_Win32.h"
+#include "ecore_win32_private.h"
+
+
+static int _ecore_win32_dnd_init_count = 0;
+
+static HANDLE DataToHandle(const char *data, int size)
+{
+ char *ptr;
+ ptr = (char *)GlobalAlloc(GMEM_FIXED, size);
+ memcpy(ptr, data, size);
+ return ptr;
+}
+
+
+int
+ecore_win32_dnd_init()
+{
+ if (_ecore_win32_dnd_init_count > 0)
+ {
+ _ecore_win32_dnd_init_count++;
+ return _ecore_win32_dnd_init_count;
+ }
+
+ if (OleInitialize(NULL) != S_OK)
+ return 0;
+
+ _ecore_win32_dnd_init_count++;
+
+ return _ecore_win32_dnd_init_count;
+}
+
+int ecore_win32_dnd_shutdown()
+{
+ _ecore_win32_dnd_init_count--;
+ if (_ecore_win32_dnd_init_count > 0) return _ecore_win32_dnd_init_count;
+
+ OleUninitialize();
+
+ if (_ecore_win32_dnd_init_count < 0) _ecore_win32_dnd_init_count = 0;
+
+ return _ecore_win32_dnd_init_count;
+}
+
+int ecore_win32_dnd_begin(const char *data,
+ int size)
+{
+ IDataObject *pDataObject = NULL;
+ IDropSource *pDropSource = NULL;
+ FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM stgmed = { TYMED_HGLOBAL, { 0 }, 0 };
+ int res = 0;
+
+ if (data == NULL)
+ return 0;
+ if (size < 0)
+ size = strlen(data) + 1;
+
+ stgmed.hGlobal = DataToHandle(data, size);
+
+ // create the data object
+ pDataObject = (IDataObject *)_ecore_win32_dnd_data_object_new((void *)&fmtetc,
+ (void *)&stgmed,
+ 1);
+ pDropSource = (IDropSource *)_ecore_win32_dnd_drop_source_new();
+
+ if (pDataObject && pDropSource)
+ {
+ DWORD dwResult;
+ DWORD dwEffect = DROPEFFECT_COPY;
+
+ // do the drag-drop!
+ dwResult = DoDragDrop(pDataObject, pDropSource, DROPEFFECT_COPY, &dwEffect);
+
+ // finished. Check the return values to see if we need to do anything else
+ if (dwResult == DRAGDROP_S_DROP)
+ {
+ //printf(">>> \"%s\" Dropped <<<\n", str);
+ if(dwEffect == DROPEFFECT_MOVE)
+ {
+ // remove the data we just dropped from active document
+ }
+ }
+ //else if (dwResult == DRAGDROP_S_CANCEL)
+ // printf("DND cancelled\n");
+ //else
+ // printf("DND error\n");
+
+ res = 1;
+ }
+
+ _ecore_win32_dnd_data_object_free(pDataObject);
+ _ecore_win32_dnd_drop_source_free(pDropSource);
+
+ // cleanup
+ ReleaseStgMedium(&stgmed);
+ return (int)res;
+}
+
+int ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window,
+ Ecore_Win32_Dnd_DropTarget_Callback callback)
+{
+ struct _Ecore_Win32_Window *wnd = (struct _Ecore_Win32_Window *)window;
+
+ if (window == NULL)
+ return 0;
+
+ wnd->dnd_drop_target = _ecore_win32_dnd_register_drop_window(wnd->window,
+ callback,
+ (void *)wnd);
+ return (int)(wnd->dnd_drop_target != NULL);
+}
+
+void ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window)
+{
+ struct _Ecore_Win32_Window *wnd = (struct _Ecore_Win32_Window *)window;
+
+ if (window == NULL)
+ return;
+
+ if (wnd->dnd_drop_target != NULL)
+ _ecore_win32_dnd_unregister_drop_window(wnd->window, wnd->dnd_drop_target);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <ole2.h>
+
+#include "Ecore_Win32.h"
+#include "ecore_win32_private.h"
+
+#include "ecore_win32_dnd_enumformatetc.h"
+#include "ecore_win32_dnd_data_object.h"
+
+
+static HGLOBAL DupGlobalMem(HGLOBAL hMem)
+{
+ DWORD len = (DWORD)GlobalSize(hMem);
+ PVOID source = GlobalLock(hMem);
+ PVOID dest = GlobalAlloc(GMEM_FIXED, len);
+ memcpy(dest, source, len);
+ GlobalUnlock(hMem);
+ return dest;
+}
+
+// structors
+
+DataObject::DataObject(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count)
+{
+ assert(fmtetc != NULL);
+ assert(stgmed != NULL);
+ assert(count > 0);
+
+ // reference count must ALWAYS start at 1
+ ref_count_ = 1;
+ formats_num_ = count;
+
+ format_etc_ = new FORMATETC[count];
+ stg_medium_ = new STGMEDIUM[count];
+
+ for(int i = 0; i < count; i++)
+ {
+ format_etc_[i] = fmtetc[i];
+ stg_medium_[i] = stgmed[i];
+ }
+}
+
+DataObject::~DataObject()
+{
+ delete[] format_etc_;
+ delete[] stg_medium_;
+}
+
+
+// IUnknown
+
+HRESULT DataObject::QueryInterface(REFIID iid, void **ppvObject)
+{
+ // check to see what interface has been requested
+ if ((iid == IID_IDataObject) || (iid == IID_IUnknown))
+ {
+ AddRef();
+ *ppvObject = this;
+ return S_OK;
+ }
+ *ppvObject = 0;
+ return E_NOINTERFACE;
+}
+
+ULONG DataObject::AddRef()
+{
+ return InterlockedIncrement(&ref_count_);
+}
+
+ULONG DataObject::Release()
+{
+ LONG count = InterlockedDecrement(&ref_count_);
+ if(count == 0)
+ {
+ delete this;
+ return 0;
+ }
+ return count;
+}
+
+// IDataObject
+
+HRESULT DataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
+{
+ assert(pMedium != NULL);
+ int idx;
+
+ // try to match the specified FORMATETC with one of our supported formats
+ if((idx = lookup_format_etc(pFormatEtc)) == -1)
+ return DV_E_FORMATETC;
+
+ // found a match - transfer data into supplied storage medium
+ pMedium->tymed = format_etc_[idx].tymed;
+ pMedium->pUnkForRelease = 0;
+
+ // copy the data into the caller's storage medium
+ switch(format_etc_[idx].tymed)
+ {
+ case TYMED_HGLOBAL:
+ pMedium->hGlobal = DupGlobalMem(stg_medium_[idx].hGlobal);
+ break;
+
+ default:
+ return DV_E_FORMATETC;
+ }
+
+ return S_OK;
+}
+
+HRESULT DataObject::GetDataHere(FORMATETC *pFormatEtc, STGMEDIUM *pmedium)
+{
+ return DATA_E_FORMATETC;
+}
+
+HRESULT DataObject::QueryGetData(FORMATETC *pFormatEtc)
+{
+ return (lookup_format_etc(pFormatEtc) == -1) ? DV_E_FORMATETC : S_OK;
+}
+
+HRESULT DataObject::GetCanonicalFormatEtc(FORMATETC *pFormatEct, FORMATETC *pFormatEtcOut)
+{
+ // Apparently we have to set this field to NULL even though we don't do anything else
+ pFormatEtcOut->ptd = NULL;
+ return E_NOTIMPL;
+}
+
+HRESULT DataObject::SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT DataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc)
+{
+ // only the get direction is supported for OLE
+ if(dwDirection == DATADIR_GET)
+ {
+ // for Win2k+ you can use the SHCreateStdEnumFmtEtc API call, however
+ // to support all Windows platforms we need to implement IEnumFormatEtc ourselves.
+ return CreateEnumFormatEtc(formats_num_, format_etc_, ppEnumFormatEtc);
+ }
+ else
+ {
+ // the direction specified is not supported for drag+drop
+ return E_NOTIMPL;
+ }
+}
+
+HRESULT DataObject::DAdvise(FORMATETC *pFormatEtc, DWORD advf, IAdviseSink *, DWORD *)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+HRESULT DataObject::DUnadvise(DWORD dwConnection)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+HRESULT DataObject::EnumDAdvise(IEnumSTATDATA **ppEnumAdvise)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+// internal helper function
+
+int DataObject::lookup_format_etc(FORMATETC *pFormatEtc)
+{
+ // check each of our formats in turn to see if one matches
+ for(int i = 0; i < formats_num_; i++)
+ {
+ if((format_etc_[i].tymed & pFormatEtc->tymed) &&
+ (format_etc_[i].cfFormat == pFormatEtc->cfFormat) &&
+ (format_etc_[i].dwAspect == pFormatEtc->dwAspect))
+ {
+ // return index of stored format
+ return i;
+ }
+ }
+
+ // error, format not found
+ return -1;
+}
+
+void *_ecore_win32_dnd_data_object_new(void *fmtetc, void *stgmeds, int count)
+{
+ IDataObject *object = new DataObject((FORMATETC *)fmtetc, (STGMEDIUM *)stgmeds, (UINT)count);
+ assert(object != NULL);
+ return object;
+}
+
+void _ecore_win32_dnd_data_object_free(void *data_object)
+{
+ if (!data_object)
+ return;
+
+ IDataObject *object = (IDataObject *)data_object;
+ object->Release();
+}
--- /dev/null
+#ifndef __ECORE_WIN32_DND_DATA_OBJECT_H__
+#define __ECORE_WIN32_DND_DATA_OBJECT_H__
+
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <objbase.h>
+
+
+class DataObject : public IDataObject
+{
+ private:
+
+ LONG ref_count_;
+ int formats_num_;
+ FORMATETC *format_etc_;
+ STGMEDIUM *stg_medium_;
+
+ private: // internal helper function
+
+ int lookup_format_etc(FORMATETC *format_etc);
+
+ public: // structors
+
+ DataObject(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count);
+ ~DataObject();
+
+ public: // IUnknown
+
+ HRESULT __stdcall QueryInterface(REFIID iid, void **ppvObject);
+ ULONG __stdcall AddRef();
+ ULONG __stdcall Release();
+
+ public: // IDataObject
+
+ HRESULT __stdcall GetData(FORMATETC *pFormatEtc, STGMEDIUM *pmedium);
+ HRESULT __stdcall GetDataHere(FORMATETC *pFormatEtc, STGMEDIUM *pmedium);
+ HRESULT __stdcall QueryGetData(FORMATETC *pFormatEtc);
+ HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC *pFormatEct, FORMATETC *pFormatEtcOut);
+ HRESULT __stdcall SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease);
+ HRESULT __stdcall EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
+ HRESULT __stdcall DAdvise(FORMATETC *pFormatEtc, DWORD advf, IAdviseSink *, DWORD *);
+ HRESULT __stdcall DUnadvise(DWORD dwConnection);
+ HRESULT __stdcall EnumDAdvise(IEnumSTATDATA **ppEnumAdvise);
+};
+
+
+#endif /* __ECORE_WIN32_DND_DATA_OBJECT_H__ */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+
+#include "ecore_win32_dnd_drop_source.h"
+
+#include "ecore_win32_private.h"
+
+// structors
+
+// reference count must ALWAYS start at 1
+DropSource::DropSource() : ref_count_(1)
+{ }
+
+
+// IUnknown
+
+HRESULT DropSource::QueryInterface(REFIID iid, void **ppvObject)
+{
+ // check to see what interface has been requested
+ if (iid == IID_IDropSource || iid == IID_IUnknown)
+ {
+ AddRef();
+ *ppvObject = this;
+ return S_OK;
+ }
+ *ppvObject = 0;
+ return E_NOINTERFACE;
+}
+
+ULONG DropSource::AddRef()
+{
+ return InterlockedIncrement(&ref_count_);
+}
+
+ULONG DropSource::Release()
+{
+ LONG count = InterlockedDecrement(&ref_count_);
+ if(count == 0)
+ {
+ delete this;
+ return 0;
+ }
+ return count;
+}
+
+
+// IDropSource
+
+HRESULT DropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
+{
+ // if the Escape key has been pressed since the last call, cancel the drop
+ if(fEscapePressed == TRUE)
+ return DRAGDROP_S_CANCEL;
+
+ // if the LeftMouse button has been released, then do the drop!
+ if((grfKeyState & MK_LBUTTON) == 0)
+ return DRAGDROP_S_DROP;
+
+ // continue with the drag-drop
+ return S_OK;
+}
+
+HRESULT DropSource::GiveFeedback(DWORD dwEffect)
+{
+ return DRAGDROP_S_USEDEFAULTCURSORS;
+}
+
+
+// ecore_win32 private functions
+
+void *_ecore_win32_dnd_drop_source_new()
+{
+ IDropSource *object = new DropSource();
+ assert(object != NULL);
+ return object;
+}
+
+void _ecore_win32_dnd_drop_source_free(void *drop_source)
+{
+ if (!drop_source)
+ return;
+
+ IDropSource *object = (IDropSource *)drop_source;
+ object->Release();
+}
--- /dev/null
+#ifndef __ECORE_WIN32_DND_DROP_SOURCE_H__
+#define __ECORE_WIN32_DND_DROP_SOURCE_H__
+
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <ole2.h>
+
+#include "Ecore_Win32.h"
+
+
+class DropSource : public IDropSource
+{
+ private:
+
+ LONG ref_count_;
+
+ public: // structors
+
+ DropSource();
+
+ public: // IUnknown
+
+ HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject);
+ ULONG __stdcall AddRef();
+ ULONG __stdcall Release();
+
+ public: // IDropSource
+
+ HRESULT __stdcall QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
+ HRESULT __stdcall GiveFeedback(DWORD dwEffect);
+};
+
+
+#endif /* __ECORE_WIN32_DND_DROP_SOURCE_H__ */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_win32_dnd_drop_target.h"
+
+#include "ecore_win32_private.h"
+
+
+// structors
+
+DropTarget::DropTarget(HWND window, Ecore_Win32_Dnd_DropTarget_Callback callback, void *window_obj_ptr)
+ : ref_count_(1)
+ , window_(window)
+ , allow_drop_(false)
+ , drop_callback_(callback)
+ ,drop_callback_ptr_(window_obj_ptr)
+{ }
+
+
+// IUnknown
+
+HRESULT DropTarget::QueryInterface(REFIID iid, void **ppvObject)
+{
+ // check to see what interface has been requested
+ if (iid == IID_IDropTarget || iid == IID_IUnknown)
+ {
+ AddRef();
+ *ppvObject = this;
+ return S_OK;
+ }
+ *ppvObject = 0;
+
+ return E_NOINTERFACE;
+}
+
+ULONG DropTarget::AddRef()
+{
+ return InterlockedIncrement(&ref_count_);
+}
+
+ULONG DropTarget::Release()
+{
+ LONG count = InterlockedDecrement(&ref_count_);
+ if (count == 0)
+ {
+ delete this;
+ return 0;
+ }
+
+ return count;
+}
+
+
+// IDropTarget
+
+HRESULT DropTarget::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
+{
+ // does the dataobject contain data we want?
+ allow_drop_ = QueryDataObject(pDataObject) &&
+ (drop_callback_ == NULL ||
+ (drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_ENTER, pt.x, pt.y, NULL, 0) != 0));
+
+ if (allow_drop_)
+ {
+ // get the dropeffect based on keyboard state
+ *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
+ SetFocus(window_);
+ //PositionCursor(_hwnd, pt);
+ }
+ else
+ *pdwEffect = DROPEFFECT_NONE;
+ return S_OK;
+}
+
+HRESULT DropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
+{
+ allow_drop_ =
+ (drop_callback_ == NULL) ||
+ (drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_OVER, pt.x, pt.y, NULL, 0) != 0);
+
+ if (allow_drop_)
+ {
+ *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
+ //PositionCursor(m_hWnd, pt);
+ }
+ else
+ {
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+
+ return S_OK;
+}
+
+HRESULT DropTarget::DragLeave()
+{
+ POINT pt;
+
+ GetCursorPos(&pt);
+ if (drop_callback_ != NULL)
+ drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_LEAVE, pt.x, pt.y, NULL, 0);
+
+ return S_OK;
+}
+
+HRESULT DropTarget::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
+{
+ if (allow_drop_)
+ {
+ // construct a FORMATETC object
+ FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM stgmed;
+
+ // See if the dataobject contains any TEXT stored as a HGLOBAL
+ if (pDataObject->QueryGetData(&fmtetc) == S_OK)
+ {
+ // Yippie! the data is there, so go get it!
+ if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK)
+ {
+ // we asked for the data as a HGLOBAL, so access it appropriately
+ PVOID data = GlobalLock(stgmed.hGlobal);
+ UINT size = GlobalSize(stgmed.hGlobal);
+
+ if (drop_callback_ != NULL)
+ {
+ drop_callback_(drop_callback_ptr_,
+ ECORE_WIN32_DND_EVENT_DROP,
+ pt.x, pt.y,
+ data, size);
+ }
+
+ GlobalUnlock(stgmed.hGlobal);
+
+ // release the data using the COM API
+ ReleaseStgMedium(&stgmed);
+ }
+ }
+ *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
+ }
+ else
+ {
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+
+ return S_OK;
+}
+
+
+// internal helper function
+
+DWORD DropTarget::DropEffect(DWORD grfKeyState, POINTL pt, DWORD dwAllowed)
+{
+ DWORD dwEffect = 0;
+
+ // 1. check "pt" -> do we allow a drop at the specified coordinates?
+
+ // 2. work out that the drop-effect should be based on grfKeyState
+ if (grfKeyState & MK_CONTROL)
+ {
+ dwEffect = dwAllowed & DROPEFFECT_COPY;
+ }
+ else if (grfKeyState & MK_SHIFT)
+ {
+ dwEffect = dwAllowed & DROPEFFECT_MOVE;
+ }
+
+ // 3. no key-modifiers were specified (or drop effect not allowed), so
+ // base the effect on those allowed by the dropsource
+ if (dwEffect == 0)
+ {
+ if (dwAllowed & DROPEFFECT_COPY) dwEffect = DROPEFFECT_COPY;
+ if (dwAllowed & DROPEFFECT_MOVE) dwEffect = DROPEFFECT_MOVE;
+ }
+
+ return dwEffect;
+}
+
+bool DropTarget::QueryDataObject(IDataObject *pDataObject)
+{
+ FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+
+ // does the data object support CF_TEXT using a HGLOBAL?
+ return pDataObject->QueryGetData(&fmtetc) == S_OK;
+}
+
+
+// ecore_win32 private functions
+
+void *_ecore_win32_dnd_register_drop_window(HWND hwnd, Ecore_Win32_Dnd_DropTarget_Callback callback, void *ptr)
+{
+ DropTarget *pDropTarget = new DropTarget(hwnd, callback, ptr);
+
+ if (pDropTarget == NULL)
+ return NULL;
+
+ // acquire a strong lock
+ if (FAILED(CoLockObjectExternal(pDropTarget, TRUE, FALSE)))
+ {
+ delete pDropTarget;
+ return NULL;
+ }
+
+ // tell OLE that the window is a drop target
+ if (FAILED(RegisterDragDrop(hwnd, pDropTarget)))
+ {
+ delete pDropTarget;
+ return NULL;
+ }
+
+ return pDropTarget;
+}
+
+void _ecore_win32_dnd_unregister_drop_window(HWND hwnd, void *drop_target)
+{
+ IDropTarget *pDropTarget = (IDropTarget *)drop_target;
+
+ if (drop_target == NULL)
+ return;
+
+ // remove drag+drop
+ RevokeDragDrop(hwnd);
+
+ // remove the strong lock
+ CoLockObjectExternal(pDropTarget, FALSE, TRUE);
+
+ // release our own reference
+ pDropTarget->Release();
+}
--- /dev/null
+#ifndef __ECORE_WIN32_DND_DROP_TARGET_H__
+#define __ECORE_WIN32_DND_DROP_TARGET_H__
+
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <ole2.h>
+
+#include "Ecore_Win32.h"
+
+
+class DropTarget : public IDropTarget
+{
+ private:
+
+ LONG ref_count_;
+ HWND window_;
+ bool allow_drop_;
+ Ecore_Win32_Dnd_DropTarget_Callback drop_callback_;
+ void *drop_callback_ptr_;
+
+ private: // internal helper function
+
+ DWORD DropEffect(DWORD grfKeyState, POINTL pt, DWORD dwAllowed);
+ bool QueryDataObject(IDataObject *pDataObject);
+
+ public: // structors
+
+ DropTarget(HWND hwnd, Ecore_Win32_Dnd_DropTarget_Callback callback, void *window_obj_ptr);
+
+public: // IUnknown
+
+ HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject);
+ ULONG __stdcall AddRef();
+ ULONG __stdcall Release();
+
+ public: // IDropTarget
+
+ HRESULT __stdcall DragEnter(IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
+ HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
+ HRESULT __stdcall DragLeave();
+ HRESULT __stdcall Drop(IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
+};
+
+
+#endif /* __ECORE_WIN32_DND_DROP_TARGET_H__ */
--- /dev/null
+
+#include <ole2.h>
+
+#include "ecore_win32_dnd_enumformatetc.h"
+
+
+// structors
+
+CEnumFormatEtc::CEnumFormatEtc(FORMATETC *format_etc, int formats_num)
+ : ref_count_(1)
+ , index_(0)
+ , formats_num_(formats_num)
+ , format_etc_(new FORMATETC[formats_num])
+{
+ // make a new copy of each FORMATETC structure
+ for (unsigned int i = 0; i < formats_num_; i++)
+ {
+ DeepCopyFormatEtc(&format_etc_[i], &format_etc[i]);
+ }
+}
+
+CEnumFormatEtc::~CEnumFormatEtc()
+{
+ if (format_etc_)
+ {
+ // first free any DVTARGETDEVICE structures
+ for (ULONG i = 0; i < formats_num_; i++)
+ {
+ if (format_etc_[i].ptd)
+ CoTaskMemFree(format_etc_[i].ptd);
+ }
+
+ // now free the main array
+ delete[] format_etc_;
+ }
+}
+
+// IUnknown
+
+ULONG __stdcall CEnumFormatEtc::AddRef(void)
+{
+ // increment object reference count
+ return InterlockedIncrement(&ref_count_);
+}
+
+ULONG __stdcall CEnumFormatEtc::Release(void)
+{
+ // decrement object reference count
+ LONG count = InterlockedDecrement(&ref_count_);
+
+ if (count == 0)
+ {
+ delete this;
+ return 0;
+ }
+ else
+ {
+ return count;
+ }
+}
+
+HRESULT __stdcall CEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject)
+{
+ // check to see what interface has been requested
+ if ((iid == IID_IEnumFORMATETC) || (iid == IID_IUnknown))
+ {
+ AddRef();
+ *ppvObject = this;
+ return S_OK;
+ }
+ else
+ {
+ *ppvObject = 0;
+ return E_NOINTERFACE;
+ }
+}
+
+// IEnumFormatEtc
+
+HRESULT CEnumFormatEtc::Reset(void)
+{
+ index_ = 0;
+ return S_OK;
+}
+
+HRESULT CEnumFormatEtc::Skip(ULONG celt)
+{
+ index_ += celt;
+ return (index_ <= formats_num_) ? S_OK : S_FALSE;
+}
+
+HRESULT CEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc)
+{
+ HRESULT hResult;
+
+ // make a duplicate enumerator
+ hResult = CreateEnumFormatEtc(formats_num_, format_etc_, ppEnumFormatEtc);
+
+ if (hResult == S_OK)
+ {
+ // manually set the index state
+ ((CEnumFormatEtc *)*ppEnumFormatEtc)->index_ = index_;
+ }
+
+ return hResult;
+}
+
+HRESULT CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
+{
+ ULONG copied = 0;
+
+ // validate arguments
+ if ((celt == 0) || (pFormatEtc == 0))
+ return E_INVALIDARG;
+
+ // copy the FORMATETC structures into the caller's buffer
+ while (index_ < formats_num_ && copied < celt)
+ {
+ DeepCopyFormatEtc(&pFormatEtc[copied], &format_etc_[index_]);
+ copied++;
+ index_++;
+ }
+
+ // store result
+ if (pceltFetched != 0)
+ *pceltFetched = copied;
+
+ // did we copy all that was requested?
+ return (copied == celt) ? S_OK : S_FALSE;
+}
+
+// external functions
+
+void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source)
+{
+ // copy the source FORMATETC into dest
+ *dest = *source;
+
+ if (source->ptd)
+ {
+ // allocate memory for the DVTARGETDEVICE if necessary
+ dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
+
+ // copy the contents of the source DVTARGETDEVICE into dest->ptd
+ *(dest->ptd) = *(source->ptd);
+ }
+}
+
+HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc)
+{
+ if((cfmt == 0) || (afmt == 0) || (ppEnumFormatEtc == 0))
+ return E_INVALIDARG;
+
+ *ppEnumFormatEtc = new CEnumFormatEtc(afmt, cfmt);
+
+ return (*ppEnumFormatEtc) ? S_OK : E_OUTOFMEMORY;
+}
--- /dev/null
+#ifndef __ECORE_WIN32_DND_ENUMFORMATETC_H__
+#define __ECORE_WIN32_DND_ENUMFORMATETC_H__
+
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <objbase.h>
+
+
+class CEnumFormatEtc : public IEnumFORMATETC
+{
+ private:
+
+ LONG ref_count_; // Reference count for this COM interface
+ ULONG index_; // current enumerator index
+ ULONG formats_num_; // number of FORMATETC members
+ FORMATETC *format_etc_; // array of FORMATETC objects
+
+ public: // structors
+
+ CEnumFormatEtc(FORMATETC *pFormatEtc, int nNumFormats);
+
+ ~CEnumFormatEtc();
+
+ public: // IUnknown
+
+ HRESULT __stdcall QueryInterface (REFIID iid, void ** ppvObject);
+
+ ULONG __stdcall AddRef (void);
+
+ ULONG __stdcall Release (void);
+
+ public: // IEnumFormatEtc
+
+ HRESULT __stdcall Next (ULONG celt, FORMATETC * rgelt, ULONG * pceltFetched);
+
+ HRESULT __stdcall Skip (ULONG celt);
+
+ HRESULT __stdcall Reset (void);
+
+ HRESULT __stdcall Clone (IEnumFORMATETC ** ppEnumFormatEtc);
+};
+
+void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source);
+
+HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc);
+
+
+#endif /* __ECORE_WIN32_DND_ENUMFORMATETC_H__ */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h> /* for printf */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <windowsx.h>
+
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
+#include "Ecore_Win32.h"
+#include "ecore_win32_private.h"
+
+
+/***** Private declarations *****/
+
+
+static Ecore_Win32_Window *_ecore_win32_mouse_down_last_window = NULL;
+static Ecore_Win32_Window *_ecore_win32_mouse_down_last_last_window = NULL;
+static long _ecore_win32_mouse_down_last_time = 0 ;
+static long _ecore_win32_mouse_down_last_last_time = 0 ;
+static int _ecore_win32_mouse_down_did_triple = 0;
+static int _ecore_win32_mouse_up_count = 0;
+
+static void _ecore_win32_event_free_key_down(void *data,
+ void *ev);
+
+static void _ecore_win32_event_free_key_up(void *data,
+ void *ev);
+
+static int _ecore_win32_event_keystroke_get(int key,
+ int is_extended,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose);
+
+static int _ecore_win32_event_char_get(int key,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose);
+
+
+/***** Global functions definitions *****/
+
+void
+_ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg,
+ int is_keystroke)
+{
+ Ecore_Event_Key *e;
+
+ INF("key pressed");
+
+ e = (Ecore_Event_Key *)malloc(sizeof(Ecore_Event_Key));
+ if (!e) return;
+
+ if (is_keystroke)
+ {
+ if (!_ecore_win32_event_keystroke_get(LOWORD(msg->window_param),
+ msg->data_param & 0x01000000,
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ goto store_key;
+ }
+ else
+ {
+ if (!_ecore_win32_event_char_get(LOWORD(msg->window_param),
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ }
+
+ store_key:
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+ e->timestamp = msg->time;
+
+ _ecore_win32_event_last_time = e->timestamp;
+
+ ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _ecore_win32_event_free_key_down, NULL);
+}
+
+void
+_ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg,
+ int is_keystroke)
+{
+ Ecore_Event_Key *e;
+
+ INF("key released");
+
+ e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key));
+ if (!e) return;
+
+ if (is_keystroke)
+ {
+ if (!_ecore_win32_event_keystroke_get(LOWORD(msg->window_param),
+ msg->data_param & 0x01000000,
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ goto store_key;
+ }
+ else
+ {
+ if (!_ecore_win32_event_char_get(LOWORD(msg->window_param),
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ }
+
+ store_key:
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+ e->timestamp = msg->time;
+
+ _ecore_win32_event_last_time = e->timestamp;
+
+ ecore_event_add(ECORE_EVENT_KEY_UP, e, _ecore_win32_event_free_key_up, NULL);
+}
+
+void
+_ecore_win32_event_handle_button_press(Ecore_Win32_Callback_Data *msg,
+ int button)
+{
+ Ecore_Win32_Window *window;
+
+ INF("mouse button pressed");
+
+ window = (Ecore_Win32_Window *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ if (button > 3)
+ {
+ Ecore_Event_Mouse_Wheel *e;
+
+ e = (Ecore_Event_Mouse_Wheel *)calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->direction = 0;
+ /* wheel delta is positive or negative, never 0 */
+ e->z = GET_WHEEL_DELTA_WPARAM(msg->window_param) > 0 ? -1 : 1;
+ e->x = GET_X_LPARAM(msg->data_param);
+ e->y = GET_Y_LPARAM(msg->data_param);
+ e->timestamp = msg->time;
+
+ _ecore_win32_event_last_time = e->timestamp;
+ _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
+ }
+ else
+ {
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->x = GET_X_LPARAM(msg->data_param);
+ e->y = GET_Y_LPARAM(msg->data_param);
+ e->timestamp = msg->time;
+
+ _ecore_win32_event_last_time = e->timestamp;
+ _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_Event_Mouse_Button *e;
+
+ if (_ecore_win32_mouse_down_did_triple)
+ {
+ _ecore_win32_mouse_down_last_window = NULL;
+ _ecore_win32_mouse_down_last_last_window = NULL;
+ _ecore_win32_mouse_down_last_time = 0;
+ _ecore_win32_mouse_down_last_last_time = 0;
+ }
+
+ e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->buttons = button;
+ e->x = GET_X_LPARAM(msg->data_param);
+ e->y = GET_Y_LPARAM(msg->data_param);
+ e->timestamp = msg->time;
+
+ if (((e->timestamp - _ecore_win32_mouse_down_last_time) <= (long)(1000 * _ecore_win32_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window))
+ e->double_click = 1;
+
+ if (((e->timestamp - _ecore_win32_mouse_down_last_last_time) <= (long)(2 * 1000 * _ecore_win32_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window) &&
+ (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_last_window))
+ {
+ e->triple_click = 1;
+ _ecore_win32_mouse_down_did_triple = 1;
+ }
+ else
+ _ecore_win32_mouse_down_did_triple = 0;
+
+ if (!e->double_click && !e->triple_click)
+ _ecore_win32_mouse_up_count = 0;
+
+ _ecore_win32_event_last_time = e->timestamp;
+ _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
+
+ if (!_ecore_win32_mouse_down_did_triple)
+ {
+ _ecore_win32_mouse_down_last_last_window = _ecore_win32_mouse_down_last_window;
+ _ecore_win32_mouse_down_last_window = (Ecore_Win32_Window *)e->window;
+ _ecore_win32_mouse_down_last_last_time = _ecore_win32_mouse_down_last_time;
+ _ecore_win32_mouse_down_last_time = e->timestamp;
+ }
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+ }
+}
+
+void
+_ecore_win32_event_handle_button_release(Ecore_Win32_Callback_Data *msg,
+ int button)
+{
+ Ecore_Win32_Window *window;
+
+ INF("mouse button released");
+
+ window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->x = GET_X_LPARAM(msg->data_param);
+ e->y = GET_Y_LPARAM(msg->data_param);
+ e->timestamp = msg->time;
+
+ _ecore_win32_event_last_time = e->timestamp;
+ _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_Event_Mouse_Button *e;
+
+ e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->buttons = button;
+ e->x = GET_X_LPARAM(msg->data_param);
+ e->y = GET_Y_LPARAM(msg->data_param);
+ e->timestamp = msg->time;
+
+ _ecore_win32_mouse_up_count++;
+
+ if ((_ecore_win32_mouse_up_count >= 2) &&
+ ((e->timestamp - _ecore_win32_mouse_down_last_time) <= (long)(1000 * _ecore_win32_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window))
+ e->double_click = 1;
+
+ if ((_ecore_win32_mouse_up_count >= 3) &&
+ ((e->timestamp - _ecore_win32_mouse_down_last_last_time) <= (long)(2 * 1000 * _ecore_win32_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window) &&
+ (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_last_window))
+ e->triple_click = 1;
+
+ _ecore_win32_event_last_time = e->timestamp;
+ _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_win32_event_handle_motion_notify(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Event_Mouse_Move *e;
+
+ INF("mouse moved");
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ e->x = GET_X_LPARAM(msg->data_param);
+ e->y = GET_Y_LPARAM(msg->data_param);
+ e->timestamp = msg->time;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_enter_notify(Ecore_Win32_Callback_Data *msg)
+{
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ INF("mouse in");
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ e->x = msg->x;
+ e->y = msg->y;
+ e->timestamp = msg->time;
+
+ _ecore_win32_event_last_time = e->timestamp;
+ _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_Win32_Event_Mouse_In *e;
+
+ e = (Ecore_Win32_Event_Mouse_In *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_In));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ e->x = msg->x;
+ e->y = msg->y;
+ e->time = msg->time ;
+
+ _ecore_win32_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_MOUSE_IN, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_win32_event_handle_leave_notify(Ecore_Win32_Callback_Data *msg)
+{
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ INF("mouse out");
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ e->x = msg->x;
+ e->y = msg->y;
+ e->timestamp = msg->time;
+
+ _ecore_win32_event_last_time = e->timestamp;
+ _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_Win32_Event_Mouse_Out *e;
+
+ e = (Ecore_Win32_Event_Mouse_Out *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Out));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ e->x = msg->x;
+ e->y = msg->y;
+ e->time = msg->time;
+
+ _ecore_win32_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_MOUSE_OUT, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_win32_event_handle_focus_in(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Focus_In *e;
+
+ INF("focus in");
+
+ e = (Ecore_Win32_Event_Window_Focus_In *)calloc(1, sizeof(Ecore_Win32_Event_Window_Focus_In));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ e->time = _ecore_win32_event_last_time;
+ _ecore_win32_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_focus_out(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Focus_Out *e;
+
+ INF("focus out");
+
+ e = (Ecore_Win32_Event_Window_Focus_Out *)calloc(1, sizeof(Ecore_Win32_Event_Window_Focus_Out));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ e->time = _ecore_win32_event_last_time;
+ _ecore_win32_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_expose(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Damage *e;
+
+ INF("window expose");
+
+ e = (Ecore_Win32_Event_Window_Damage *)calloc(1, sizeof(Ecore_Win32_Event_Window_Damage));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ e->x = msg->update.left;
+ e->y = msg->update.top;
+ e->width = msg->update.right - msg->update.left;
+ e->height = msg->update.bottom - msg->update.top;
+
+ e->time = _ecore_win32_event_last_time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_create_notify(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Create *e;
+
+ INF("window create notify");
+
+ e = calloc(1, sizeof(Ecore_Win32_Event_Window_Create));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ e->time = _ecore_win32_event_last_time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CREATE, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_destroy_notify(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Destroy *e;
+
+ INF("window destroy notify");
+
+ e = calloc(1, sizeof(Ecore_Win32_Event_Window_Destroy));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ e->time = _ecore_win32_event_last_time;
+ if (e->window == _ecore_win32_event_last_window) _ecore_win32_event_last_window = NULL;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DESTROY, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_map_notify(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Show *e;
+
+ INF("window map notify");
+
+ e = calloc(1, sizeof(Ecore_Win32_Event_Window_Show));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ e->time = _ecore_win32_event_last_time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_SHOW, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_unmap_notify(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Hide *e;
+
+ INF("window unmap notify");
+
+ e = calloc(1, sizeof(Ecore_Win32_Event_Window_Hide));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ e->time = _ecore_win32_event_last_time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_HIDE, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_configure_notify(Ecore_Win32_Callback_Data *msg)
+{
+ WINDOWINFO wi;
+ Ecore_Win32_Event_Window_Configure *e;
+ WINDOWPOS *window_pos;
+
+ INF("window configure notify");
+
+ e = calloc(1, sizeof(Ecore_Win32_Event_Window_Configure));
+ if (!e) return;
+
+ window_pos = (WINDOWPOS *)msg->data_param;
+ wi.cbSize = sizeof(WINDOWINFO);
+ if (!GetWindowInfo(window_pos->hwnd, &wi))
+ {
+ free(e);
+ return;
+ }
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ e->abovewin = (void *)GetWindowLong(window_pos->hwndInsertAfter, GWL_USERDATA);
+ e->x = wi.rcClient.left;
+ e->y = wi.rcClient.top;
+ e->width = wi.rcClient.right - wi.rcClient.left;
+ e->height = wi.rcClient.bottom - wi.rcClient.top;
+ e->time = _ecore_win32_event_last_time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_resize(Ecore_Win32_Callback_Data *msg)
+{
+ RECT rect;
+ Ecore_Win32_Event_Window_Resize *e;
+
+ INF("window resize");
+
+ if (!GetClientRect(msg->window, &rect))
+ return;
+
+ e = calloc(1, sizeof(Ecore_Win32_Event_Window_Resize));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ e->width = rect.right - rect.left;
+ e->height = rect.bottom - rect.top;
+ e->time = _ecore_win32_event_last_time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_RESIZE, e, NULL, NULL);
+}
+
+void
+_ecore_win32_event_handle_delete_request(Ecore_Win32_Callback_Data *msg)
+{
+ Ecore_Win32_Event_Window_Delete_Request *e;
+
+ INF("window delete request");
+
+ e = calloc(1, sizeof(Ecore_Win32_Event_Window_Delete_Request));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ e->time = _ecore_win32_event_last_time;
+
+ ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
+}
+
+
+/***** Private functions definitions *****/
+
+static void
+_ecore_win32_event_free_key_down(void *data __UNUSED__,
+ void *ev)
+{
+ Ecore_Event_Key *e;
+
+ e = ev;
+ if (e->keyname) free((char *)e->keyname);
+ if (e->key) free((char *)e->key);
+ if (e->string) free((char *)e->string);
+ free(e);
+}
+
+static void
+_ecore_win32_event_free_key_up(void *data __UNUSED__,
+ void *ev)
+{
+ Ecore_Event_Key *e;
+
+ e = ev;
+ if (e->keyname) free((char *)e->keyname);
+ if (e->key) free((char *)e->key);
+ if (e->string) free((char *)e->string);
+ free(e);
+}
+
+static int
+_ecore_win32_event_keystroke_get(int key,
+ int is_extended,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose)
+{
+ char *kn;
+ char *ks;
+ char *kc;
+
+ *keyname = NULL;
+ *keysymbol = NULL;
+ *keycompose = NULL;
+
+ switch (key)
+ {
+ /* Keystroke */
+ case VK_PRIOR:
+ if (is_extended)
+ {
+ kn = "Prior";
+ ks = "Prior";
+ kc = "Prior";
+ }
+ else
+ {
+ kn = "KP_Prior";
+ ks = "KP_9";
+ kc = "KP_Prior";
+ }
+ break;
+ case VK_NEXT:
+ if (is_extended)
+ {
+ kn = "Next";
+ ks = "Next";
+ kc = "Next";
+ }
+ else
+ {
+ kn = "KP_Next";
+ ks = "KP_3";
+ kc = "KP_Next";
+ }
+ break;
+ case VK_END:
+ if (is_extended)
+ {
+ kn = "End";
+ ks = "End";
+ kc = "End";
+ }
+ else
+ {
+ kn = "KP_End";
+ ks = "KP_1";
+ kc = "KP_End";
+ }
+ break;
+ case VK_HOME:
+ if (is_extended)
+ {
+ kn = "Home";
+ ks = "Home";
+ kc = "Home";
+ }
+ else
+ {
+ kn = "KP_Home";
+ ks = "KP_7";
+ kc = "KP_Home";
+ }
+ break;
+ case VK_LEFT:
+ if (is_extended)
+ {
+ kn = "Left";
+ ks = "Left";
+ kc = "Left";
+ }
+ else
+ {
+ kn = "KP_Left";
+ ks = "KP_4";
+ kc = "KP_Left";
+ }
+ break;
+ case VK_UP:
+ if (is_extended)
+ {
+ kn = "Up";
+ ks = "Up";
+ kc = "Up";
+ }
+ else
+ {
+ kn = "KP_Up";
+ ks = "KP_8";
+ kc = "KP_Up";
+ }
+ break;
+ case VK_RIGHT:
+ if (is_extended)
+ {
+ kn = "Right";
+ ks = "Right";
+ kc = "Right";
+ }
+ else
+ {
+ kn = "KP_Right";
+ ks = "KP_6";
+ kc = "KP_Right";
+ }
+ break;
+ case VK_DOWN:
+ if (is_extended)
+ {
+ kn = "Down";
+ ks = "Down";
+ kc = "Down";
+ }
+ else
+ {
+ kn = "KP_Down";
+ ks = "KP_2";
+ kc = "KP_Down";
+ }
+ break;
+ case VK_INSERT:
+ if (is_extended)
+ {
+ kn = "Insert";
+ ks = "Insert";
+ kc = "Insert";
+ }
+ else
+ {
+ kn = "KP_Insert";
+ ks = "KP_0";
+ kc = "KP_Insert";
+ }
+ break;
+ case VK_DELETE:
+ if (is_extended)
+ {
+ kn = "Delete";
+ ks = "Delete";
+ kc = "Delete";
+ }
+ else
+ {
+ kn = "KP_Delete";
+ ks = "KP_Decimal";
+ kc = "KP_Delete";
+ }
+ break;
+ case VK_F1:
+ kn = "F1";
+ ks = "F1";
+ kc = "";
+ break;
+ case VK_F2:
+ kn = "F2";
+ ks = "F2";
+ kc = "";
+ break;
+ case VK_F3:
+ kn = "F3";
+ ks = "F3";
+ kc = "";
+ break;
+ case VK_F4:
+ kn = "F4";
+ ks = "F4";
+ kc = "";
+ break;
+ case VK_F5:
+ kn = "F5";
+ ks = "F5";
+ kc = "";
+ break;
+ case VK_F6:
+ kn = "F6";
+ ks = "F6";
+ kc = "";
+ break;
+ case VK_F7:
+ kn = "F7";
+ ks = "F7";
+ kc = "";
+ break;
+ case VK_F8:
+ kn = "F8";
+ ks = "F8";
+ kc = "";
+ break;
+ case VK_F9:
+ kn = "F9";
+ ks = "F9";
+ kc = "";
+ break;
+ case VK_F10:
+ kn = "F10";
+ ks = "F10";
+ kc = "";
+ break;
+ case VK_F11:
+ kn = "F11";
+ ks = "F11";
+ kc = "";
+ break;
+ case VK_F12:
+ kn = "F12";
+ ks = "F12";
+ kc = "";
+ break;
+ case VK_F13:
+ kn = "F13";
+ ks = "F13";
+ kc = "";
+ break;
+ case VK_F14:
+ kn = "F14";
+ ks = "F14";
+ kc = "";
+ break;
+ case VK_F15:
+ kn = "F15";
+ ks = "F15";
+ kc = "";
+ break;
+ case VK_F16:
+ kn = "F16";
+ ks = "F16";
+ kc = "";
+ break;
+ case VK_F17:
+ kn = "F17";
+ ks = "F17";
+ kc = "";
+ break;
+ case VK_F18:
+ kn = "F18";
+ ks = "F18";
+ kc = "";
+ break;
+ case VK_F19:
+ kn = "F19";
+ ks = "F19";
+ kc = "";
+ break;
+ case VK_F20:
+ kn = "F20";
+ ks = "F20";
+ kc = "";
+ break;
+ case VK_F21:
+ kn = "F21";
+ ks = "F21";
+ kc = "";
+ break;
+ case VK_F22:
+ kn = "F22";
+ ks = "F22";
+ kc = "";
+ break;
+ case VK_F23:
+ kn = "F23";
+ ks = "F23";
+ kc = "";
+ break;
+ case VK_F24:
+ kn = "F24";
+ ks = "F24";
+ kc = "";
+ break;
+ default:
+ /* other non keystroke characters */
+ return 0;
+ }
+ *keyname = strdup(kn);
+ if (!*keyname) return 0;
+ *keysymbol = strdup(ks);
+ if (!*keysymbol)
+ {
+ free(*keyname);
+ *keyname = NULL;
+ return 0;
+ }
+ *keycompose = strdup(kc);
+ if (!*keycompose)
+ {
+ free(*keyname);
+ free(*keysymbol);
+ *keyname = NULL;
+ *keysymbol = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+_ecore_win32_event_char_get(int key,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose)
+{
+ char kn[32];
+ char ks[32];
+ char kc[32];
+
+ *keyname = NULL;
+ *keysymbol = NULL;
+ *keycompose = NULL;
+
+ switch (key)
+ {
+ case VK_BACK:
+ strncpy(kn, "BackSpace", 32);
+ strncpy(ks, "BackSpace", 32);
+ strncpy(kc, "BackSpace", 32);
+ break;
+ case VK_TAB:
+ strncpy(kn, "Tab", 32);
+ strncpy(ks, "ISO_Left_Tab", 32);
+ strncpy(kc, "Tab", 32);
+ break;
+ case 0x0a:
+ /* Line feed (Shift + Enter) */
+ strncpy(kn, "LineFeed", 32);
+ strncpy(ks, "LineFeed", 32);
+ strncpy(kc, "LineFeed", 32);
+ break;
+ case VK_RETURN:
+ strncpy(kn, "Return", 32);
+ strncpy(ks, "Return", 32);
+ strncpy(kc, "Return", 32);
+ break;
+ case VK_ESCAPE:
+ strncpy(kn, "Escape", 32);
+ strncpy(ks, "Escape", 32);
+ strncpy(kc, "Escape", 32);
+ break;
+ default:
+ /* displayable characters */
+ printf (" * key : %d\n", key);
+ kn[0] = (TCHAR)key;
+ kn[1] = '\0';
+ ks[0] = (TCHAR)key;
+ ks[1] = '\0';
+ kc[0] = (TCHAR)key;
+ kc[1] = '\0';
+ break;
+ }
+ *keyname = strdup(kn);
+ if (!*keyname) return 0;
+ *keysymbol = strdup(ks);
+ if (!*keysymbol)
+ {
+ free(*keyname);
+ *keyname = NULL;
+ return 0;
+ }
+ *keycompose = strdup(kc);
+ if (!*keycompose)
+ {
+ free(*keyname);
+ free(*keysymbol);
+ *keyname = NULL;
+ *keysymbol = NULL;
+ return 0;
+ }
+
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef __ECORE_WIN32_PRIVATE_H__
+#define __ECORE_WIN32_PRIVATE_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* logging messages macros */
+extern int _ecore_win32_log_dom_global;
+
+#ifdef ECORE_WIN32_DEFAULT_LOG_COLOR
+# undef ECORE_WIN32_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_WIN32_DEFAULT_LOG_COLOR EINA_COLOR_LIGHTBLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_win32_log_dom_global , __VA_ARGS__)
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_win32_log_dom_global , __VA_ARGS__)
+
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_win32_log_dom_global , __VA_ARGS__)
+
+#define ECORE_WIN32_WINDOW_CLASS "Ecore_Win32_Window_Class"
+
+typedef struct _Ecore_Win32_Callback_Data Ecore_Win32_Callback_Data;
+
+struct _Ecore_Win32_Callback_Data
+{
+ RECT update;
+ HWND window;
+ unsigned int message;
+ WPARAM window_param;
+ LPARAM data_param;
+ long time;
+ int x;
+ int y;
+};
+
+struct _Ecore_Win32_Window
+{
+ HWND window;
+
+ DWORD style; /* used to go fullscreen to normal */
+ RECT rect; /* used to go fullscreen to normal */
+
+ unsigned int min_width;
+ unsigned int min_height;
+ unsigned int max_width;
+ unsigned int max_height;
+ unsigned int base_width;
+ unsigned int base_height;
+ unsigned int step_width;
+ unsigned int step_height;
+
+ struct {
+ unsigned int iconified : 1;
+ unsigned int modal : 1;
+ unsigned int sticky : 1;
+ unsigned int maximized_vert : 1;
+ unsigned int maximized_horz : 1;
+ unsigned int shaded : 1;
+ unsigned int hidden : 1;
+ unsigned int fullscreen : 1;
+ unsigned int above : 1;
+ unsigned int below : 1;
+ unsigned int demands_attention : 1;
+ } state;
+
+ struct {
+ unsigned int desktop : 1;
+ unsigned int dock : 1;
+ unsigned int toolbar : 1;
+ unsigned int menu : 1;
+ unsigned int utility : 1;
+ unsigned int splash : 1;
+ unsigned int dialog : 1;
+ unsigned int normal : 1;
+ } type;
+
+ unsigned int pointer_is_in : 1;
+ unsigned int borderless : 1;
+ unsigned int iconified : 1;
+ unsigned int fullscreen : 1;
+
+ struct {
+ unsigned short width;
+ unsigned short height;
+ unsigned char *mask;
+ unsigned int enabled : 1;
+ unsigned int layered : 1;
+ } shape;
+
+ void *dnd_drop_target;
+};
+
+
+extern HINSTANCE _ecore_win32_instance;
+extern double _ecore_win32_double_click_time;
+extern long _ecore_win32_event_last_time;
+extern Ecore_Win32_Window *_ecore_win32_event_last_window;
+
+
+void _ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg, int is_keystroke);
+void _ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg, int is_keystroke);
+void _ecore_win32_event_handle_button_press(Ecore_Win32_Callback_Data *msg, int button);
+void _ecore_win32_event_handle_button_release(Ecore_Win32_Callback_Data *msg, int button);
+void _ecore_win32_event_handle_motion_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_enter_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_leave_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_focus_in(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_focus_out(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_expose(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_create_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_destroy_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_map_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_unmap_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_configure_notify(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_resize(Ecore_Win32_Callback_Data *msg);
+void _ecore_win32_event_handle_delete_request(Ecore_Win32_Callback_Data *msg);
+
+void *_ecore_win32_dnd_data_object_new(void *fmtetc, void *stgmeds, int count);
+void _ecore_win32_dnd_data_object_free(void *data_object);
+void *_ecore_win32_dnd_drop_source_new();
+void _ecore_win32_dnd_drop_source_free(void *drop_source);
+void *_ecore_win32_dnd_register_drop_window(HWND hwnd,
+ Ecore_Win32_Dnd_DropTarget_Callback callback, void *ptr);
+void _ecore_win32_dnd_unregister_drop_window(HWND hwnd, void *drop_target);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __ECORE_WIN32_PRIVATE_H__ */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h> /* for printf */
+
+#define _WIN32_WINNT 0x0500 // For WS_EX_LAYERED
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <Eina.h>
+
+#include "Ecore_Win32.h"
+#include "ecore_win32_private.h"
+
+
+/***** Private declarations *****/
+
+
+typedef enum _Ecore_Win32_Window_Z_Order Ecore_Win32_Window_Z_Order;
+enum _Ecore_Win32_Window_Z_Order
+{
+ ECORE_WIN32_WINDOW_Z_ORDER_BOTTOM,
+ ECORE_WIN32_WINDOW_Z_ORDER_NOTOPMOST,
+ ECORE_WIN32_WINDOW_Z_ORDER_TOP,
+ ECORE_WIN32_WINDOW_Z_ORDER_TOPMOST
+};
+
+static Ecore_Win32_Window *ecore_win32_window_internal_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ DWORD style);
+
+
+/***** API *****/
+
+Ecore_Win32_Window *
+ecore_win32_window_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ INF("creating window with border");
+
+ return ecore_win32_window_internal_new(parent,
+ x, y,
+ width, height,
+ WS_OVERLAPPEDWINDOW | WS_SIZEBOX);
+}
+
+/* simulate X11 override windows */
+Ecore_Win32_Window *
+ecore_win32_window_override_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ INF("creating window without border");
+
+ return ecore_win32_window_internal_new(parent,
+ x, y,
+ width, height,
+ WS_POPUP);
+}
+
+void
+ecore_win32_window_free(Ecore_Win32_Window *window)
+{
+ struct _Ecore_Win32_Window *wnd = window;
+
+ if (!window) return;
+
+ INF("destroying window");
+
+ if (wnd->shape.mask != NULL)
+ free(wnd->shape.mask);
+
+ DestroyWindow(((struct _Ecore_Win32_Window *)window)->window);
+ free(window);
+}
+
+void *
+ecore_win32_window_hwnd_get(Ecore_Win32_Window *window)
+{
+ if (!window) return NULL;
+
+ return ((struct _Ecore_Win32_Window *)window)->window;
+}
+
+/*
+void
+ecore_win32_window_configure(Ecore_Win32_Window *window,
+ Ecore_Win32_Window_Z_Order order,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ HWND w;
+
+ switch (order)
+ {
+ case ECORE_WIN32_WINDOW_Z_ORDER_BOTTOM:
+ w = HWND_BOTTOM;
+ break;
+ case ECORE_WIN32_WINDOW_Z_ORDER_NOTOPMOST:
+ w = HWND_NOTOPMOST;
+ break;
+ case ECORE_WIN32_WINDOW_Z_ORDER_TOP:
+ w = HWND_TOP;
+ break;
+ case ECORE_WIN32_WINDOW_Z_ORDER_TOPMOST:
+ w = HWND_TOPMOST;
+ break;
+ default:
+ return;
+ }
+ SetWindowPos((struct _Ecore_Win32_Window *)window->window, w, x, y, width, height, ???);
+}
+*/
+
+void
+ecore_win32_window_move(Ecore_Win32_Window *window,
+ int x,
+ int y)
+{
+ RECT rect;
+ HWND w;
+
+ if (!window) return;
+
+ INF("moving window (%dx%d)", x, y);
+
+ w = ((struct _Ecore_Win32_Window *)window)->window;
+ if (!GetWindowRect(w, &rect))
+ {
+ ERR("GetWindowRect() failed");
+ return;
+ }
+
+ if (!MoveWindow(w, x, y,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+}
+
+void
+ecore_win32_window_resize(Ecore_Win32_Window *window,
+ int width,
+ int height)
+{
+ RECT rect;
+ struct _Ecore_Win32_Window *w;
+ DWORD style;
+ int x;
+ int y;
+
+ if (!window) return;
+
+ INF("resizing window (%dx%d)", width, height);
+
+ w = (struct _Ecore_Win32_Window *)window;
+ if (!GetWindowRect(w->window, &rect))
+ {
+ ERR("GetWindowRect() failed");
+ return;
+ }
+
+ x = rect.left;
+ y = rect.top;
+ rect.left = 0;
+ rect.top = 0;
+/* if (width < w->min_width) width = w->min_width; */
+/* if (width > w->max_width) width = w->max_width; */
+/* printf ("ecore_win32_window_resize 1 : %d %d %d\n", w->min_height, w->max_height, height); */
+/* if (height < w->min_height) height = w->min_height; */
+/* printf ("ecore_win32_window_resize 2 : %d %d\n", w->max_height, height); */
+/* if (height > w->max_height) height = w->max_height; */
+/* printf ("ecore_win32_window_resize 3 : %d %d\n", w->max_height, height); */
+ rect.right = width;
+ rect.bottom = height;
+ if (!(style = GetWindowLong(w->window, GWL_STYLE)))
+ {
+ ERR("GetWindowLong() failed");
+ return;
+ }
+ if (!AdjustWindowRect(&rect, style, FALSE))
+ {
+ ERR("AdjustWindowRect() failed");
+ return;
+ }
+
+ if (!MoveWindow(w->window, x, y,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+}
+
+void
+ecore_win32_window_move_resize(Ecore_Win32_Window *window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ RECT rect;
+ struct _Ecore_Win32_Window *w;
+ DWORD style;
+
+ if (!window) return;
+
+ INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height);
+
+ w = ((struct _Ecore_Win32_Window *)window);
+ rect.left = 0;
+ rect.top = 0;
+ if ((unsigned int)width < w->min_width) width = w->min_width;
+ if ((unsigned int)width > w->max_width) width = w->max_width;
+ if ((unsigned int)height < w->min_height) height = w->min_height;
+ if ((unsigned int)height > w->max_height) height = w->max_height;
+ rect.right = width;
+ rect.bottom = height;
+ if (!(style = GetWindowLong(w->window, GWL_STYLE)))
+ {
+ ERR("GetWindowLong() failed");
+ return;
+ }
+ if (!AdjustWindowRect(&rect, style, FALSE))
+ {
+ ERR("AdjustWindowRect() failed");
+ return;
+ }
+
+ if (!MoveWindow(w->window, x, y,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+}
+
+void
+ecore_win32_window_geometry_get(Ecore_Win32_Window *window,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+ RECT rect;
+ int w;
+ int h;
+
+ INF("getting window geometry");
+
+ if (!window)
+ {
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = GetSystemMetrics(SM_CXSCREEN);
+ if (height) *height = GetSystemMetrics(SM_CYSCREEN);
+
+ return;
+ }
+
+ if (!GetClientRect(((struct _Ecore_Win32_Window *)window)->window,
+ &rect))
+ {
+ ERR("GetClientRect() failed");
+
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = 0;
+ if (height) *height = 0;
+
+ return;
+ }
+
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+
+ if (!GetWindowRect(((struct _Ecore_Win32_Window *)window)->window,
+ &rect))
+ {
+ ERR("GetWindowRect() failed");
+
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = 0;
+ if (height) *height = 0;
+
+ return;
+ }
+
+ if (x) *x = rect.left;
+ if (y) *y = rect.top;
+ if (width) *width = w;
+ if (height) *height = h;
+}
+
+void
+ecore_win32_window_size_get(Ecore_Win32_Window *window,
+ int *width,
+ int *height)
+{
+ RECT rect;
+
+ INF("getting window size");
+
+ if (!window)
+ {
+ if (width) *width = GetSystemMetrics(SM_CXSCREEN);
+ if (height) *height = GetSystemMetrics(SM_CYSCREEN);
+
+ return;
+ }
+
+ if (!GetClientRect(((struct _Ecore_Win32_Window *)window)->window,
+ &rect))
+ {
+ ERR("GetClientRect() failed");
+
+ if (width) *width = 0;
+ if (height) *height = 0;
+ }
+
+ if (width) *width = rect.right - rect.left;
+ if (height) *height = rect.bottom - rect.top;
+}
+
+void
+ecore_win32_window_size_min_set(Ecore_Win32_Window *window,
+ unsigned int min_width,
+ unsigned int min_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ if (!window) return;
+
+ printf ("ecore_win32_window_size_min_set : %p %d %d\n", window, min_width, min_height);
+ w = (struct _Ecore_Win32_Window *)window;
+ w->min_width = min_width;
+ w->min_height = min_height;
+}
+
+void
+ecore_win32_window_size_min_get(Ecore_Win32_Window *window,
+ unsigned int *min_width,
+ unsigned int *min_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ if (!window) return;
+
+ w = (struct _Ecore_Win32_Window *)window;
+ printf ("ecore_win32_window_size_min_get : %p %d %d\n", window, w->min_width, w->min_height);
+ if (min_width) *min_width = w->min_width;
+ if (min_height) *min_height = w->min_height;
+}
+
+void
+ecore_win32_window_size_max_set(Ecore_Win32_Window *window,
+ unsigned int max_width,
+ unsigned int max_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ if (!window) return;
+
+ printf ("ecore_win32_window_size_max_set : %p %d %d\n", window, max_width, max_height);
+ w = (struct _Ecore_Win32_Window *)window;
+ w->max_width = max_width;
+ w->max_height = max_height;
+}
+
+void
+ecore_win32_window_size_max_get(Ecore_Win32_Window *window,
+ unsigned int *max_width,
+ unsigned int *max_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ if (!window) return;
+
+ w = (struct _Ecore_Win32_Window *)window;
+ printf ("ecore_win32_window_size_max_get : %p %d %d\n", window, w->max_width, w->max_height);
+ if (max_width) *max_width = w->max_width;
+ if (max_height) *max_height = w->max_height;
+}
+
+void
+ecore_win32_window_size_base_set(Ecore_Win32_Window *window,
+ unsigned int base_width,
+ unsigned int base_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ printf ("ecore_win32_window_size_base_set : %p %d %d\n", window, base_width, base_height);
+ if (!window) return;
+
+ w = (struct _Ecore_Win32_Window *)window;
+ w->base_width = base_width;
+ w->base_height = base_height;
+}
+
+void
+ecore_win32_window_size_base_get(Ecore_Win32_Window *window,
+ unsigned int *base_width,
+ unsigned int *base_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ if (!window) return;
+
+ w = (struct _Ecore_Win32_Window *)window;
+ printf ("ecore_win32_window_size_base_get : %p %d %d\n", window, w->base_width, w->base_height);
+ if (base_width) *base_width = w->base_width;
+ if (base_height) *base_height = w->base_height;
+}
+
+void
+ecore_win32_window_size_step_set(Ecore_Win32_Window *window,
+ unsigned int step_width,
+ unsigned int step_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ printf ("ecore_win32_window_size_step_set : %p %d %d\n", window, step_width, step_height);
+ if (!window) return;
+
+ w = (struct _Ecore_Win32_Window *)window;
+ w->step_width = step_width;
+ w->step_height = step_height;
+}
+
+void
+ecore_win32_window_size_step_get(Ecore_Win32_Window *window,
+ unsigned int *step_width,
+ unsigned int *step_height)
+{
+ struct _Ecore_Win32_Window *w;
+
+ if (!window) return;
+
+ w = (struct _Ecore_Win32_Window *)window;
+ printf ("ecore_win32_window_size_step_get : %p %d %d\n", window, w->step_width, w->step_height);
+ if (step_width) *step_width = w->step_width;
+ if (step_height) *step_height = w->step_height;
+}
+
+void
+ecore_win32_window_shape_set(Ecore_Win32_Window *window,
+ unsigned short width,
+ unsigned short height,
+ unsigned char *mask)
+{
+ struct _Ecore_Win32_Window *wnd;
+ HRGN rgn;
+ int x;
+ int y;
+ OSVERSIONINFO version_info;
+
+ if (window == NULL)
+ return;
+
+ wnd = (struct _Ecore_Win32_Window *)window;
+
+ if (mask == NULL)
+ {
+ wnd->shape.enabled = 0;
+ if (wnd->shape.layered != 0)
+ {
+ wnd->shape.layered = 0;
+#if defined(WS_EX_LAYERED)
+ SetLastError(0);
+ if (!SetWindowLongPtr(wnd->window, GWL_EXSTYLE,
+ GetWindowLong(wnd->window, GWL_EXSTYLE) & (~WS_EX_LAYERED)) &&
+ (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ if (!RedrawWindow(wnd->window, NULL, NULL,
+ RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN))
+ {
+ ERR("RedrawWindow() failed");
+ return;
+ }
+#endif
+ }
+ else
+ if (!SetWindowRgn(wnd->window, NULL, TRUE))
+ {
+ ERR("SetWindowRgn() failed");
+ }
+ return;
+ }
+
+ if (width == 0 || height == 0)
+ return;
+
+ wnd->shape.enabled = 1;
+
+ if (width != wnd->shape.width || height != wnd->shape.height)
+ {
+ wnd->shape.width = width;
+ wnd->shape.height = height;
+ if (wnd->shape.mask != NULL)
+ {
+ free(wnd->shape.mask);
+ wnd->shape.mask = NULL;
+ }
+ wnd->shape.mask = malloc(width * height);
+ }
+ memcpy(wnd->shape.mask, mask, width * height);
+
+ wnd->shape.layered = 0;
+
+#if defined(WS_EX_LAYERED)
+ version_info.dwOSVersionInfoSize = sizeof(version_info);
+ if (GetVersionEx(&version_info) == TRUE && version_info.dwMajorVersion == 5)
+ {
+ SetLastError(0);
+ if (!SetWindowLongPtr(wnd->window, GWL_EXSTYLE,
+ GetWindowLong(wnd->window, GWL_EXSTYLE) | WS_EX_LAYERED) &&
+ (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ wnd->shape.layered = 1;
+ return;
+ }
+#endif
+
+ if (!(rgn = CreateRectRgn(0, 0, 0, 0)))
+ {
+ ERR("CreateRectRgn() failed");
+ return;
+ }
+ for (y = 0; y < height; y++)
+ {
+ HRGN rgnLine;
+
+ if (!(rgnLine = CreateRectRgn(0, 0, 0, 0)))
+ {
+ ERR("CreateRectRgn() failed");
+ return;
+ }
+ for (x = 0; x < width; x++)
+ {
+ if (mask[y * width + x] > 0)
+ {
+ HRGN rgnDot;
+
+ if (!(rgnDot = CreateRectRgn(x, y, x + 1, y + 1)))
+ {
+ ERR("CreateRectRgn() failed");
+ return;
+ }
+ if (CombineRgn(rgnLine, rgnLine, rgnDot, RGN_OR) == ERROR)
+ {
+ ERR("CombineRgn() has not created a new region");
+ }
+ if (!DeleteObject(rgnDot))
+ {
+ ERR("DeleteObject() failed");
+ return;
+ }
+ }
+ }
+ if (CombineRgn(rgn, rgn, rgnLine, RGN_OR) == ERROR)
+ {
+ ERR("CombineRgn() has not created a new region");
+ }
+ if (!DeleteObject(rgnLine))
+ {
+ ERR("DeleteObject() failed");
+ return;
+ }
+ }
+ if (!SetWindowRgn(wnd->window, rgn, TRUE))
+ {
+ ERR("SetWindowRgn() failed");
+ }
+}
+
+void
+ecore_win32_window_show(Ecore_Win32_Window *window)
+{
+ if (!window) return;
+
+ INF("showing window");
+
+ ShowWindow(((struct _Ecore_Win32_Window *)window)->window, SW_SHOWNORMAL);
+ if (!UpdateWindow(((struct _Ecore_Win32_Window *)window)->window))
+ {
+ ERR("UpdateWindow() failed");
+ }
+}
+
+/* FIXME: seems to block the taskbar */
+void
+ecore_win32_window_hide(Ecore_Win32_Window *window)
+{
+ if (!window) return;
+
+ INF("hiding window");
+
+ ShowWindow(((struct _Ecore_Win32_Window *)window)->window, SW_HIDE);
+}
+
+void
+ecore_win32_window_raise(Ecore_Win32_Window *window)
+{
+ if (!window) return;
+
+ INF("raising window");
+
+ if (!SetWindowPos(((struct _Ecore_Win32_Window *)window)->window,
+ HWND_TOP, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
+ {
+ ERR("SetWindowPos() failed");
+ }
+}
+
+void
+ecore_win32_window_lower(Ecore_Win32_Window *window)
+{
+ if (!window) return;
+
+ INF("lowering window");
+
+ if (!SetWindowPos(((struct _Ecore_Win32_Window *)window)->window,
+ HWND_BOTTOM, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
+ {
+ ERR("SetWindowPos() failed");
+ }
+}
+
+void
+ecore_win32_window_title_set(Ecore_Win32_Window *window,
+ const char *title)
+{
+ if (!window) return;
+
+ if (!title || !title[0]) return;
+
+ INF("setting window title");
+
+ if (!SetWindowText(((struct _Ecore_Win32_Window *)window)->window, title))
+ {
+ ERR("SetWindowText() failed");
+ }
+}
+
+void
+ecore_win32_window_focus_set(Ecore_Win32_Window *window)
+{
+ if (!window) return;
+
+ INF("focusing window");
+
+ if (!SetFocus(((struct _Ecore_Win32_Window *)window)->window))
+ {
+ ERR("SetFocus() failed");
+ }
+}
+
+void
+ecore_win32_window_iconified_set(Ecore_Win32_Window *window,
+ int on)
+{
+ struct _Ecore_Win32_Window *ew;
+
+ if (!window) return;
+
+ ew = (struct _Ecore_Win32_Window *)window;
+ if (((ew->iconified) && (on)) ||
+ ((!ew->iconified) && (!on)))
+ return;
+
+ INF("iconifying window: %s", on ? "yes" : "no");
+
+ ShowWindow(ew->window, on ? SW_MINIMIZE : SW_RESTORE);
+ ew->iconified = on;
+}
+
+void
+ecore_win32_window_borderless_set(Ecore_Win32_Window *window,
+ int on)
+{
+ RECT rect;
+ DWORD style;
+ struct _Ecore_Win32_Window *ew;
+ HWND w;
+
+ if (!window) return;
+
+ ew = (struct _Ecore_Win32_Window *)window;
+ if (((ew->borderless) && (on)) ||
+ ((!ew->borderless) && (!on)))
+ return;
+
+ INF("setting window without border: %s", on ? "yes" : "no");
+
+ w = ew->window;
+
+ style = GetWindowLong(w, GWL_STYLE);
+ if (on)
+ {
+ if (!GetClientRect(w, &rect))
+ {
+ ERR("GetClientRect() failed");
+ return;
+ }
+ SetLastError(0);
+ if (!SetWindowLongPtr(w, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME)) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ }
+ else
+ {
+ if (!GetWindowRect(w, &rect))
+ {
+ ERR("GetWindowRect() failed");
+ return;
+ }
+ style |= WS_CAPTION | WS_THICKFRAME;
+ if (!AdjustWindowRect (&rect, style, FALSE))
+ {
+ ERR("AdjustWindowRect() failed");
+ return;
+ }
+ SetLastError(0);
+ if (!SetWindowLongPtr(w, GWL_STYLE, style) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ }
+ if (!SetWindowPos(w, HWND_TOPMOST,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ SWP_NOMOVE | SWP_FRAMECHANGED))
+ {
+ ERR("SetWindowPos() failed");
+ return;
+ }
+ ew->borderless = on;
+}
+
+void
+ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window,
+ int on)
+{
+ struct _Ecore_Win32_Window *ew;
+ HWND w;
+
+ if (!window) return;
+
+ ew = (struct _Ecore_Win32_Window *)window;
+ if (((ew->fullscreen) && (on)) ||
+ ((!ew->fullscreen) && (!on)))
+ return;
+
+ INF("setting fullscreen: %s", on ? "yes" : "no");
+
+ ew->fullscreen = !!on;
+ w = ew->window;
+
+ if (on)
+ {
+ DWORD style;
+
+ if (!GetWindowRect(w, &ew->rect))
+ {
+ ERR("GetWindowRect() failed");
+ return;
+ }
+ if (!(ew->style = GetWindowLong(w, GWL_STYLE)))
+ {
+ ERR("GetWindowLong() failed");
+ return;
+ }
+ style = ew->style & ~WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX;
+ style |= WS_VISIBLE | WS_POPUP;
+ SetLastError(0);
+ if (!SetWindowLongPtr(w, GWL_STYLE, style) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ SetLastError(0);
+ if (!SetWindowLongPtr(w, GWL_EXSTYLE, WS_EX_TOPMOST) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ if (!SetWindowPos(w, HWND_TOPMOST, 0, 0,
+ GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN),
+ SWP_NOCOPYBITS | SWP_SHOWWINDOW))
+ {
+ ERR("SetWindowPos() failed");
+ return;
+ }
+ }
+ else
+ {
+ SetLastError(0);
+ if (!SetWindowLongPtr(w, GWL_STYLE, ew->style) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ SetLastError(0);
+ if (!SetWindowLongPtr(w, GWL_EXSTYLE, 0) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ return;
+ }
+ if (!SetWindowPos(w, HWND_NOTOPMOST,
+ ew->rect.left,
+ ew->rect.top,
+ ew->rect.right - ew->rect.left,
+ ew->rect.bottom - ew->rect.top,
+ SWP_NOCOPYBITS | SWP_SHOWWINDOW))
+ {
+ ERR("SetWindowPos() failed");
+ return;
+ }
+ }
+}
+
+void
+ecore_win32_window_cursor_set(Ecore_Win32_Window *window,
+ Ecore_Win32_Cursor *cursor)
+{
+ INF("setting cursor");
+
+ if (!SetClassLong(((struct _Ecore_Win32_Window *)window)->window,
+ GCL_HCURSOR, (LONG)cursor))
+ {
+ ERR("SetClassLong() failed");
+ }
+}
+
+void
+ecore_win32_window_state_set(Ecore_Win32_Window *window,
+ Ecore_Win32_Window_State *state,
+ unsigned int num)
+{
+ unsigned int i;
+
+ if (!window || !state || !num)
+ return;
+
+ INF("setting cursor state");
+
+ for (i = 0; i < num; i++)
+ {
+ switch (state[i])
+ {
+ case ECORE_WIN32_WINDOW_STATE_ICONIFIED:
+ ((struct _Ecore_Win32_Window *)window)->state.iconified = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MODAL:
+ ((struct _Ecore_Win32_Window *)window)->state.modal = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_STICKY:
+ ((struct _Ecore_Win32_Window *)window)->state.sticky = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT:
+ ((struct _Ecore_Win32_Window *)window)->state.maximized_vert = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ:
+ ((struct _Ecore_Win32_Window *)window)->state.maximized_horz = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MAXIMIZED:
+ ((struct _Ecore_Win32_Window *)window)->state.maximized_horz = 1;
+ ((struct _Ecore_Win32_Window *)window)->state.maximized_vert = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_SHADED:
+ ((struct _Ecore_Win32_Window *)window)->state.shaded = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_HIDDEN:
+ ((struct _Ecore_Win32_Window *)window)->state.hidden = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_FULLSCREEN:
+ ((struct _Ecore_Win32_Window *)window)->state.fullscreen = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_ABOVE:
+ ((struct _Ecore_Win32_Window *)window)->state.above = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_BELOW:
+ ((struct _Ecore_Win32_Window *)window)->state.below = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION:
+ ((struct _Ecore_Win32_Window *)window)->state.demands_attention = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_UNKNOWN:
+ /* nothing to be done */
+ break;
+ }
+ }
+}
+
+void
+ecore_win32_window_state_request_send(Ecore_Win32_Window *window,
+ Ecore_Win32_Window_State state,
+ unsigned int set)
+{
+ struct _Ecore_Win32_Window *ew;
+ HWND w;
+
+ if (!window) return;
+
+ ew = (struct _Ecore_Win32_Window *)window;
+ w = ew->window;
+
+ INF("sending cursor state");
+
+ switch (state)
+ {
+ case ECORE_WIN32_WINDOW_STATE_ICONIFIED:
+ if (ew->state.iconified)
+ ecore_win32_window_iconified_set(window, set);
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MODAL:
+ ew->state.modal = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_STICKY:
+ ew->state.sticky = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT:
+ if (ew->state.maximized_vert)
+ {
+ RECT rect;
+ int y;
+ int height;
+
+ if (!SystemParametersInfo(SPI_GETWORKAREA, 0,
+ &rect, 0))
+ {
+ ERR("SystemParametersInfo() failed");
+ break;
+ }
+ y = rect.top;
+ height = rect.bottom - rect.top;
+
+ if (!GetClientRect(w, &rect))
+ {
+ ERR("GetClientRect() failed");
+ break;
+ }
+
+ if (!MoveWindow(w, rect.left, y,
+ rect.right - rect.left,
+ height,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+ }
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ:
+ if (ew->state.maximized_horz)
+ {
+ RECT rect;
+
+ if (!GetClientRect(w, &rect))
+ {
+ ERR("GetClientRect() failed");
+ break;
+ }
+
+ if (!MoveWindow(w, 0, rect.top,
+ GetSystemMetrics(SM_CXSCREEN),
+ rect.bottom - rect.top,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+ }
+ break;
+ case ECORE_WIN32_WINDOW_STATE_MAXIMIZED:
+ if (ew->state.maximized_vert && ew->state.maximized_horz)
+ {
+ RECT rect;
+
+ if (!SystemParametersInfo(SPI_GETWORKAREA, 0,
+ &rect, 0))
+ {
+ ERR("SystemParametersInfo() failed");
+ break;
+ }
+
+ if (!MoveWindow(w, 0, 0,
+ GetSystemMetrics(SM_CXSCREEN),
+ rect.bottom - rect.top,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+ }
+ break;
+ case ECORE_WIN32_WINDOW_STATE_SHADED:
+ ew->state.shaded = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_HIDDEN:
+ ew->state.hidden = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_FULLSCREEN:
+ if (ew->state.fullscreen)
+ ecore_win32_window_fullscreen_set(window, set);
+ break;
+ case ECORE_WIN32_WINDOW_STATE_ABOVE:
+ if (ew->state.above)
+ if (!SetWindowPos(w, HWND_TOP,
+ 0, 0,
+ 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW))
+ {
+ ERR("SetWindowPos() failed");
+ }
+ break;
+ case ECORE_WIN32_WINDOW_STATE_BELOW:
+ if (ew->state.below)
+ if (!SetWindowPos(w, HWND_BOTTOM,
+ 0, 0,
+ 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW))
+ {
+ ERR("SetWindowPos() failed");
+ }
+ break;
+ case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION:
+ ew->state.demands_attention = 1;
+ break;
+ case ECORE_WIN32_WINDOW_STATE_UNKNOWN:
+ /* nothing to be done */
+ break;
+ }
+}
+
+void
+ecore_win32_window_type_set(Ecore_Win32_Window *window,
+ Ecore_Win32_Window_Type type)
+{
+ if (!window)
+ return;
+
+ INF("setting window type");
+
+ switch (type)
+ {
+ case ECORE_WIN32_WINDOW_TYPE_DESKTOP:
+ ((struct _Ecore_Win32_Window *)window)->type.desktop = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_DOCK:
+ ((struct _Ecore_Win32_Window *)window)->type.dock = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_TOOLBAR:
+ ((struct _Ecore_Win32_Window *)window)->type.toolbar = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_MENU:
+ ((struct _Ecore_Win32_Window *)window)->type.menu = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_UTILITY:
+ ((struct _Ecore_Win32_Window *)window)->type.utility = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_SPLASH:
+ ((struct _Ecore_Win32_Window *)window)->type.splash = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_DIALOG:
+ ((struct _Ecore_Win32_Window *)window)->type.dialog = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_NORMAL:
+ ((struct _Ecore_Win32_Window *)window)->type.normal = 1;
+ break;
+ case ECORE_WIN32_WINDOW_TYPE_UNKNOWN:
+ ((struct _Ecore_Win32_Window *)window)->type.normal = 1;
+ break;
+ }
+}
+
+
+/***** Private functions definitions *****/
+
+static Ecore_Win32_Window *
+ecore_win32_window_internal_new(Ecore_Win32_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height,
+ DWORD style)
+{
+ RECT rect;
+ struct _Ecore_Win32_Window *w;
+ int minimal_width;
+ int minimal_height;
+
+ w = (struct _Ecore_Win32_Window *)calloc(1, sizeof(struct _Ecore_Win32_Window));
+ if (!w)
+ {
+ ERR("malloc() failed");
+ return NULL;
+ }
+
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+ if (!AdjustWindowRect(&rect, style, FALSE))
+ {
+ ERR("AdjustWindowRect() failed");
+ free(w);
+ return NULL;
+ }
+
+ minimal_width = GetSystemMetrics(SM_CXMIN);
+ minimal_height = GetSystemMetrics(SM_CYMIN);
+/* if (((rect.right - rect.left) < minimal_width) || */
+/* ((rect.bottom - rect.top) < minimal_height)) */
+/* { */
+/* fprintf (stderr, "[Ecore] [Win32] ERROR !!\n"); */
+/* fprintf (stderr, " Wrong size %ld\n", rect.right - rect.left); */
+/* free(w); */
+/* return NULL; */
+/* } */
+ if ((rect.right - rect.left) < minimal_width)
+ {
+ rect.right = rect.left + minimal_width;
+ }
+
+ w->window = CreateWindowEx(0,
+ ECORE_WIN32_WINDOW_CLASS, "",
+ style,
+ x, y,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ parent ? ((struct _Ecore_Win32_Window *)parent)->window : NULL,
+ NULL, _ecore_win32_instance, NULL);
+ if (!w->window)
+ {
+ ERR("CreateWindowEx() failed");
+ free(w);
+ return NULL;
+ }
+
+ SetLastError(0);
+ if (!SetWindowLongPtr(w->window, GWL_USERDATA, (LONG)w) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLongPtr() failed");
+ DestroyWindow(w->window);
+ free(w);
+ return NULL;
+ }
+
+ w->min_width = 0;
+ w->min_height = 0;
+ w->max_width = 32767;
+ w->max_height = 32767;
+ w->base_width = -1;
+ w->base_height = -1;
+ w->step_width = -1;
+ w->step_height = -1;
+
+ w->state.iconified = 0;
+ w->state.modal = 0;
+ w->state.sticky = 0;
+ w->state.maximized_vert = 0;
+ w->state.maximized_horz = 0;
+ w->state.shaded = 0;
+ w->state.hidden = 0;
+ w->state.fullscreen = 0;
+ w->state.above = 0;
+ w->state.below = 0;
+ w->state.demands_attention = 0;
+
+ w->type.desktop = 0;
+ w->type.dock = 0;
+ w->type.toolbar = 0;
+ w->type.menu = 0;
+ w->type.utility = 0;
+ w->type.splash = 0;
+ w->type.dialog = 0;
+ w->type.normal = 0;
+
+ w->pointer_is_in = 0;
+ w->borderless = 0;
+ w->iconified = 0;
+ w->fullscreen = 0;
+
+ return w;
+}
--- /dev/null
+.libs
+.deps
+Makefile
+Makefile.in
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef __ECORE_WINCE_H__
+#define __ECORE_WINCE_H__
+
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WINCE
+# ifdef EFL_ECORE_WINCE_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_WINCE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WINCE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef _ECORE_EVAS_H
+typedef void Ecore_WinCE_Window;
+#endif
+
+
+/* Events */
+
+typedef struct _Ecore_WinCE_Event_Mouse_In Ecore_WinCE_Event_Mouse_In;
+typedef struct _Ecore_WinCE_Event_Mouse_Out Ecore_WinCE_Event_Mouse_Out;
+typedef struct _Ecore_WinCE_Event_Window_Focus_In Ecore_WinCE_Event_Window_Focus_In;
+typedef struct _Ecore_WinCE_Event_Window_Focus_Out Ecore_WinCE_Event_Window_Focus_Out;
+typedef struct _Ecore_WinCE_Event_Window_Damage Ecore_WinCE_Event_Window_Damage;
+typedef struct _Ecore_WinCE_Event_Window_Create Ecore_WinCE_Event_Window_Create;
+typedef struct _Ecore_WinCE_Event_Window_Destroy Ecore_WinCE_Event_Window_Destroy;
+typedef struct _Ecore_WinCE_Event_Window_Hide Ecore_WinCE_Event_Window_Hide;
+typedef struct _Ecore_WinCE_Event_Window_Show Ecore_WinCE_Event_Window_Show;
+typedef struct _Ecore_WinCE_Event_Window_Delete_Request Ecore_WinCE_Event_Window_Delete_Request;
+
+struct _Ecore_WinCE_Event_Mouse_In
+{
+ Ecore_WinCE_Window *window;
+ int x;
+ int y;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Mouse_Out
+{
+ Ecore_WinCE_Window *window;
+ int x;
+ int y;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Focus_In
+{
+ Ecore_WinCE_Window *window;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Focus_Out
+{
+ Ecore_WinCE_Window *window;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Damage
+{
+ Ecore_WinCE_Window *window;
+ int x;
+ int y;
+ int width;
+ int height;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Create
+{
+ Ecore_WinCE_Window *window;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Destroy
+{
+ Ecore_WinCE_Window *window;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Hide
+{
+ Ecore_WinCE_Window *window;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Show
+{
+ Ecore_WinCE_Window *window;
+ long time;
+};
+
+struct _Ecore_WinCE_Event_Window_Delete_Request
+{
+ Ecore_WinCE_Window *window;
+ long time;
+};
+
+
+EAPI extern int ECORE_WINCE_EVENT_MOUSE_IN;
+EAPI extern int ECORE_WINCE_EVENT_MOUSE_OUT;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_IN;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_DAMAGE;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_CREATE;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_DESTROY;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_HIDE;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_SHOW;
+EAPI extern int ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST;
+
+
+/* Core */
+
+EAPI int ecore_wince_init();
+EAPI int ecore_wince_shutdown();
+EAPI long ecore_wince_current_time_get(void);
+EAPI void ecore_wince_message_loop_begin (void);
+
+/* Window */
+
+EAPI Ecore_WinCE_Window *ecore_wince_window_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI void ecore_wince_window_free(Ecore_WinCE_Window *window);
+
+EAPI void *ecore_wince_window_hwnd_get(Ecore_WinCE_Window *window);
+
+EAPI void ecore_wince_window_move(Ecore_WinCE_Window *window,
+ int x,
+ int y);
+
+EAPI void ecore_wince_window_resize(Ecore_WinCE_Window *window,
+ int width,
+ int height);
+
+EAPI void ecore_wince_window_move_resize(Ecore_WinCE_Window *window,
+ int x,
+ int y,
+ int width,
+ int height);
+
+EAPI void ecore_wince_window_show(Ecore_WinCE_Window *window);
+
+EAPI void ecore_wince_window_hide(Ecore_WinCE_Window *window);
+
+EAPI void ecore_wince_window_title_set(Ecore_WinCE_Window *window,
+ const char *title);
+
+EAPI void ecore_wince_window_backend_set(Ecore_WinCE_Window *window, int backend);
+
+EAPI void ecore_wince_window_suspend_set(Ecore_WinCE_Window *window, int (*suspend)(int));
+
+EAPI void ecore_wince_window_resume_set(Ecore_WinCE_Window *window, int (*resume)(int));
+
+EAPI void ecore_wince_window_geometry_get(Ecore_WinCE_Window *window,
+ int *x,
+ int *y,
+ int *width,
+ int *height);
+
+EAPI void ecore_wince_window_size_get(Ecore_WinCE_Window *window,
+ int *width,
+ int *height);
+
+EAPI void ecore_wince_window_fullscreen_set(Ecore_WinCE_Window *window,
+ int on);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ECORE_WINCE_H__ */
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_input \
+@EFL_ECORE_WINCE_BUILD@ \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@ \
+@WIN32_CPPFLAGS@
+
+AM_CFLAGS = @WIN32_CFLAGS@
+
+
+if BUILD_ECORE_WINCE
+
+lib_LTLIBRARIES = libecore_wince.la
+
+include_HEADERS = \
+Ecore_WinCE.h
+
+libecore_wince_la_SOURCES = \
+ecore_wince.c \
+ecore_wince_event.c \
+ecore_wince_window.c
+
+libecore_wince_la_LIBADD = \
+@WIN32_LIBS@ \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+$(top_builddir)/src/lib/ecore/libecore.la \
+@EVAS_LIBS@ \
+@EINA_LIBS@ \
+@EVIL_LIBS@
+
+libecore_wince_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_wince_release_info@
+
+endif
+
+EXTRA_DIST = ecore_wince_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h> /* for printf */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
+#include "Ecore_WinCE.h"
+#include "ecore_wince_private.h"
+
+
+/***** Global declarations *****/
+
+double _ecore_wince_double_click_time = 0.25;
+long _ecore_wince_event_last_time = 0;
+Ecore_WinCE_Window *_ecore_wince_event_last_window = NULL;
+HINSTANCE _ecore_wince_instance = NULL;
+int _ecore_wince_log_dom_global = -1;
+
+int ECORE_WINCE_EVENT_MOUSE_IN = 0;
+int ECORE_WINCE_EVENT_MOUSE_OUT = 0;
+int ECORE_WINCE_EVENT_WINDOW_FOCUS_IN = 0;
+int ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT = 0;
+int ECORE_WINCE_EVENT_WINDOW_DAMAGE = 0;
+int ECORE_WINCE_EVENT_WINDOW_CREATE = 0;
+int ECORE_WINCE_EVENT_WINDOW_DESTROY = 0;
+int ECORE_WINCE_EVENT_WINDOW_SHOW = 0;
+int ECORE_WINCE_EVENT_WINDOW_HIDE = 0;
+int ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST = 0;
+
+
+/***** Private declarations *****/
+
+static int _ecore_wince_init_count = 0;
+
+LRESULT CALLBACK _ecore_wince_window_procedure(HWND window,
+ UINT message,
+ WPARAM window_param,
+ LPARAM data_param);
+
+static void _ecore_wince_error_print_cb(const Eina_Log_Domain *d,
+ Eina_Log_Level level,
+ const char *file,
+ const char *fnc,
+ int line,
+ const char *fmt,
+ void *data,
+ va_list args);
+
+
+/***** API *****/
+
+int
+ecore_wince_init()
+{
+ WNDCLASS wc;
+
+ if (++_ecore_wince_init_count != 1)
+ return _ecore_wince_init_count;
+
+ if (!eina_init())
+ return --_ecore_wince_init_count;
+
+ eina_log_print_cb_set(_ecore_wince_error_print_cb, NULL);
+ _ecore_wince_log_dom_global = eina_log_domain_register("ecore_wince", ECORE_WINCE_DEFAULT_LOG_COLOR);
+ if (_ecore_wince_log_dom_global < 0)
+ {
+ EINA_LOG_ERR("Ecore_WinCE: Could not register log domain");
+ goto shutdown_eina;
+ }
+
+ if (!ecore_event_init())
+ {
+ ERR("Ecore_WinCE: Could not init ecore_event");
+ goto unregister_log_domain;
+ }
+
+ _ecore_wince_instance = GetModuleHandle(NULL);
+ if (!_ecore_wince_instance)
+ {
+ ERR("GetModuleHandle() failed");
+ goto shutdown_ecore_event;
+ }
+
+ memset (&wc, 0, sizeof (wc));
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = _ecore_wince_window_procedure;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = _ecore_wince_instance;
+ wc.hIcon = NULL;
+ wc.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = ECORE_WINCE_WINDOW_CLASS;
+
+ if(!RegisterClass(&wc))
+ {
+ ERR("RegisterClass() failed");
+ goto free_library;
+ }
+
+ if (!ECORE_WINCE_EVENT_MOUSE_IN)
+ {
+ ECORE_WINCE_EVENT_MOUSE_IN = ecore_event_type_new();
+ ECORE_WINCE_EVENT_MOUSE_OUT = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_CREATE = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_DESTROY = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_SHOW = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_HIDE = ecore_event_type_new();
+ ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
+ }
+
+ return _ecore_wince_init_count;
+
+ free_library:
+ FreeLibrary(_ecore_wince_instance);
+ shutdown_ecore_event:
+ ecore_event_shutdown();
+ unregister_log_domain:
+ eina_log_domain_unregister(_ecore_wince_log_dom_global);
+ shutdown_eina:
+ eina_shutdown();
+
+ return --_ecore_wince_init_count;
+}
+
+int
+ecore_wince_shutdown()
+{
+ HWND task_bar;
+
+ if (--_ecore_wince_init_count != 0)
+ return _ecore_wince_init_count;
+
+ /* force task bar to be shown (in case the application exits */
+ /* while being fullscreen) */
+ task_bar = FindWindow(L"HHTaskBar", NULL);
+ if (task_bar)
+ {
+ ShowWindow(task_bar, SW_SHOW);
+ EnableWindow(task_bar, TRUE);
+ }
+
+ if (!UnregisterClass(ECORE_WINCE_WINDOW_CLASS, _ecore_wince_instance))
+ ERR("UnregisterClass() failed");
+
+ if (!FreeLibrary(_ecore_wince_instance))
+ ERR("FreeLibrary() failed");
+
+ _ecore_wince_instance = NULL;
+
+ ecore_event_shutdown();
+ eina_log_domain_unregister(_ecore_wince_log_dom_global);
+ _ecore_wince_log_dom_global = -1;
+ eina_shutdown();
+
+ return _ecore_wince_init_count;
+}
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ */
+EAPI void
+ecore_wince_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_wince_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_wince_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ */
+EAPI double
+ecore_wince_double_click_time_get(void)
+{
+ return _ecore_wince_double_click_time;
+}
+
+/**
+ * Return the last event time
+ */
+EAPI long
+ecore_wince_current_time_get(void)
+{
+ return _ecore_wince_event_last_time;
+}
+
+
+/***** Private functions definitions *****/
+
+LRESULT CALLBACK
+_ecore_wince_window_procedure(HWND window,
+ UINT message,
+ WPARAM window_param,
+ LPARAM data_param)
+{
+ Ecore_WinCE_Callback_Data *data;
+ POINTS pt;
+ DWORD coord;
+
+ data = (Ecore_WinCE_Callback_Data *)malloc(sizeof(Ecore_WinCE_Callback_Data));
+ if (!data) return DefWindowProc(window, message, window_param, data_param);
+
+ data->window = window;
+ data->message = message;
+ data->window_param = window_param;
+ data->data_param = data_param;
+ data->time = GetTickCount();
+ coord = GetMessagePos();
+ pt = MAKEPOINTS(coord);
+ data->x = pt.x;
+ data->y = pt.y;
+
+ switch (data->message)
+ {
+ /* Keyboard input notifications */
+ case WM_CHAR:
+ _ecore_wince_event_handle_key_press(data, 0);
+ break;
+ case WM_HOTKEY:
+ _ecore_wince_event_handle_key_press(data, 1);
+ break;
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ _ecore_wince_event_handle_key_press(data, 1);
+ break;
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ _ecore_wince_event_handle_key_release(data, 1);
+ break;
+ case WM_SETFOCUS:
+ _ecore_wince_event_handle_focus_in(data);
+ break;
+ case WM_KILLFOCUS:
+ _ecore_wince_event_handle_focus_out(data);
+ break;
+ /* Mouse input notifications */
+ case WM_LBUTTONDOWN:
+ _ecore_wince_event_handle_button_press(data, 1);
+ break;
+ case WM_LBUTTONUP:
+ _ecore_wince_event_handle_button_release(data, 1);
+ break;
+ case WM_MOUSEMOVE:
+ {
+ RECT rect;
+ struct _Ecore_WinCE_Window *w = NULL;
+
+ w = (struct _Ecore_WinCE_Window *)GetWindowLong(window, GWL_USERDATA);
+
+ if (GetClientRect(window, &rect))
+ {
+ POINT pt;
+
+ INF("mouse in window");
+
+ pt.x = LOWORD(data_param);
+ pt.y = HIWORD(data_param);
+ if (!PtInRect(&rect, pt))
+ {
+ if (w->pointer_is_in)
+ {
+ w->pointer_is_in = 0;
+ _ecore_wince_event_handle_leave_notify(data);
+ }
+ }
+ else
+ {
+ if (!w->pointer_is_in)
+ {
+ w->pointer_is_in = 1;
+ _ecore_wince_event_handle_enter_notify(data);
+ }
+ }
+ }
+ else
+ {
+ ERR("GetClientRect() failed");
+ }
+ _ecore_wince_event_handle_motion_notify(data);
+
+ break;
+ }
+ /* Window notifications */
+ case WM_CREATE:
+ _ecore_wince_event_handle_create_notify(data);
+ break;
+ case WM_DESTROY:
+ _ecore_wince_event_handle_destroy_notify(data);
+ break;
+ case WM_SHOWWINDOW:
+ if ((data->data_param == SW_OTHERUNZOOM) ||
+ (data->data_param == SW_OTHERUNZOOM))
+ break;
+
+ if (data->window_param)
+ _ecore_wince_event_handle_map_notify(data);
+ else
+ _ecore_wince_event_handle_unmap_notify(data);
+
+ break;
+ case WM_CLOSE:
+ _ecore_wince_event_handle_delete_request(data);
+ break;
+ /* GDI notifications */
+ case WM_PAINT:
+ {
+ PAINTSTRUCT paint;
+
+ if (BeginPaint(window, &paint))
+ {
+ data->update = paint.rcPaint;
+ _ecore_wince_event_handle_expose(data);
+ EndPaint(window, &paint);
+ }
+ break;
+ }
+ default:
+ return DefWindowProc(window, message, window_param, data_param);
+ }
+
+ return 0;
+}
+
+static void
+_ecore_wince_error_print_cb(const Eina_Log_Domain *d __UNUSED__,
+ Eina_Log_Level level __UNUSED__,
+ const char *file __UNUSED__,
+ const char *fnc,
+ int line,
+ const char *fmt,
+ void *data __UNUSED__,
+ va_list args)
+{
+ fprintf(stderr, "[%s:%d] ", fnc, line);
+ vfprintf(stderr, fmt, args);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
+#include "Ecore_WinCE.h"
+#include "ecore_wince_private.h"
+
+
+/***** Private declarations *****/
+
+static Ecore_WinCE_Window *_ecore_wince_mouse_down_last_window = NULL;
+static Ecore_WinCE_Window *_ecore_wince_mouse_down_last_last_window = NULL;
+static long _ecore_wince_mouse_down_last_time = 0;
+static long _ecore_wince_mouse_down_last_last_time = 0;
+static int _ecore_wince_mouse_down_did_triple = 0;
+static int _ecore_wince_mouse_up_count = 0;
+
+
+static void _ecore_wince_event_free_key_down(void *data,
+ void *ev);
+
+static void _ecore_wince_event_free_key_up(void *data,
+ void *ev);
+
+static int _ecore_wince_event_keystroke_get(int key,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose);
+
+static int _ecore_wince_event_char_get(int key,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose);
+
+
+/***** Global functions *****/
+
+void
+_ecore_wince_event_handle_key_press(Ecore_WinCE_Callback_Data *msg,
+ int is_keystroke)
+{
+ Ecore_Event_Key *e;
+
+ INF("key pressed");
+
+ e = (Ecore_Event_Key *)malloc(sizeof(Ecore_Event_Key));
+ if (!e) return;
+
+ if (is_keystroke)
+ {
+ if (!_ecore_wince_event_keystroke_get(LOWORD(msg->window_param),
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ }
+ else
+ {
+ if (!_ecore_wince_event_char_get(LOWORD(msg->window_param),
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ }
+
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+ e->timestamp = msg->time;
+
+ _ecore_wince_event_last_time = e->timestamp;
+
+ ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _ecore_wince_event_free_key_down, NULL);
+}
+
+void
+_ecore_wince_event_handle_key_release(Ecore_WinCE_Callback_Data *msg,
+ int is_keystroke)
+{
+ Ecore_Event_Key *e;
+
+ INF("key released");
+
+ e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key));
+ if (!e) return;
+
+ if (is_keystroke)
+ {
+ if (!_ecore_wince_event_keystroke_get(LOWORD(msg->window_param),
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ }
+ else
+ {
+ if (!_ecore_wince_event_char_get(LOWORD(msg->window_param),
+ (char **)&e->keyname,
+ (char **)&e->key,
+ (char **)&e->string))
+ {
+ free(e);
+ return;
+ }
+ }
+
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+ e->timestamp = msg->time;
+
+ _ecore_wince_event_last_time = e->timestamp;
+
+ ecore_event_add(ECORE_EVENT_KEY_UP, e, _ecore_wince_event_free_key_up, NULL);
+}
+
+void
+_ecore_wince_event_handle_button_press(Ecore_WinCE_Callback_Data *msg,
+ int button)
+{
+ Ecore_WinCE_Window *window;
+
+ INF("mouse button pressed");
+
+ window = (Ecore_WinCE_Window *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->x = LOWORD(msg->data_param);
+ e->y = HIWORD(msg->data_param);
+ e->timestamp = msg->time;
+
+ _ecore_wince_event_last_time = e->timestamp;
+ _ecore_wince_event_last_window = (Ecore_WinCE_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_Event_Mouse_Button *e;
+
+ if (_ecore_wince_mouse_down_did_triple)
+ {
+ _ecore_wince_mouse_down_last_window = NULL;
+ _ecore_wince_mouse_down_last_last_window = NULL;
+ _ecore_wince_mouse_down_last_time = 0;
+ _ecore_wince_mouse_down_last_last_time = 0;
+ }
+
+ e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->buttons = button;
+ e->x = LOWORD(msg->data_param);
+ e->y = HIWORD(msg->data_param);
+ e->timestamp = msg->time;
+
+ if (((e->timestamp - _ecore_wince_mouse_down_last_time) <= (long)(1000 * _ecore_wince_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_wince_mouse_down_last_window))
+ e->double_click = 1;
+
+ if (((e->timestamp - _ecore_wince_mouse_down_last_last_time) <= (long)(2 * 1000 * _ecore_wince_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_wince_mouse_down_last_window) &&
+ (e->window == (Ecore_Window)_ecore_wince_mouse_down_last_last_window))
+ {
+ e->triple_click = 1;
+ _ecore_wince_mouse_down_did_triple = 1;
+ }
+ else
+ _ecore_wince_mouse_down_did_triple = 0;
+
+ if (!e->double_click && !e->triple_click)
+ _ecore_wince_mouse_up_count = 0;
+
+ _ecore_wince_event_last_time = e->timestamp;
+ _ecore_wince_event_last_window = (Ecore_WinCE_Window *)e->window;
+
+ if (!_ecore_wince_mouse_down_did_triple)
+ {
+ _ecore_wince_mouse_down_last_last_window = _ecore_wince_mouse_down_last_window;
+ _ecore_wince_mouse_down_last_window = (Ecore_WinCE_Window *)e->window;
+ _ecore_wince_mouse_down_last_last_time = _ecore_wince_mouse_down_last_time;
+ _ecore_wince_mouse_down_last_time = e->timestamp;
+ }
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_wince_event_handle_button_release(Ecore_WinCE_Callback_Data *msg,
+ int button)
+{
+ Ecore_WinCE_Window *window;
+
+ INF("mouse button released");
+
+ window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->x = LOWORD(msg->data_param);
+ e->y = HIWORD(msg->data_param);
+ e->timestamp = msg->time;
+
+ _ecore_wince_event_last_time = e->timestamp;
+ _ecore_wince_event_last_window = (Ecore_WinCE_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_Event_Mouse_Button *e;
+
+ e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->buttons = button;
+ e->x = LOWORD(msg->data_param);
+ e->y = HIWORD(msg->data_param);
+ e->timestamp = msg->time;
+
+ _ecore_wince_mouse_up_count++;
+
+ if ((_ecore_wince_mouse_up_count >= 2) &&
+ ((e->timestamp - _ecore_wince_mouse_down_last_time) <= (long)(1000 * _ecore_wince_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_wince_mouse_down_last_window))
+ e->double_click = 1;
+
+ if ((_ecore_wince_mouse_up_count >= 3) &&
+ ((e->timestamp - _ecore_wince_mouse_down_last_last_time) <= (long)(2 * 1000 * _ecore_wince_double_click_time)) &&
+ (e->window == (Ecore_Window)_ecore_wince_mouse_down_last_window) &&
+ (e->window == (Ecore_Window)_ecore_wince_mouse_down_last_last_window))
+ e->triple_click = 1;
+
+ _ecore_wince_event_last_time = e->timestamp;
+ _ecore_wince_event_last_window = (Ecore_WinCE_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_wince_event_handle_motion_notify(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_Event_Mouse_Move *e;
+
+ INF("mouse moved");
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)GetWindowLong(msg->window, GWL_USERDATA);
+ e->x = LOWORD(msg->data_param);
+ e->y = HIWORD(msg->data_param);
+ e->timestamp = msg->time;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_enter_notify(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Window *window;
+
+ INF("mouse in");
+
+ window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->x = msg->x;
+ e->y = msg->y;
+ e->timestamp = msg->time;
+
+ _ecore_wince_event_last_time = e->timestamp;
+ _ecore_wince_event_last_window = (Ecore_WinCE_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_WinCE_Event_Mouse_In *e;
+
+ e = (Ecore_WinCE_Event_Mouse_In *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_In));
+ if (!e) return;
+
+ e->window = window;
+ e->x = msg->x;
+ e->y = msg->y;
+ e->time = msg->time;
+
+ _ecore_wince_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_MOUSE_IN, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_wince_event_handle_leave_notify(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Window *window;
+
+ INF("mouse out");
+
+ window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+
+ {
+ Ecore_Event_Mouse_Move *e;
+
+ e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return;
+
+ e->window = (Ecore_Window)window;
+ e->x = msg->x;
+ e->y = msg->y;
+ e->timestamp = msg->time;
+
+ _ecore_wince_event_last_time = e->timestamp;
+ _ecore_wince_event_last_window = (Ecore_WinCE_Window *)e->window;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+
+ {
+ Ecore_WinCE_Event_Mouse_Out *e;
+
+ e = (Ecore_WinCE_Event_Mouse_Out *)calloc(1, sizeof(Ecore_WinCE_Event_Mouse_Out));
+ if (!e) return;
+
+ e->window = window;
+ e->x = msg->x;
+ e->y = msg->y;
+ e->time = msg->time;
+
+ _ecore_wince_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_MOUSE_OUT, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_wince_event_handle_focus_in(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Focus_In *e;
+ struct _Ecore_WinCE_Window *window;
+
+ INF("focus in");
+
+ e = (Ecore_WinCE_Event_Window_Focus_In *)calloc(1, sizeof(Ecore_WinCE_Event_Window_Focus_In));
+ if (!e) return;
+
+ window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+
+ if (window->resume)
+ window->resume(window->backend);
+
+ e->window = window;
+
+ e->time = _ecore_wince_event_last_time;
+ _ecore_wince_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_focus_out(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Focus_Out *e;
+ struct _Ecore_WinCE_Window *window;
+
+ INF("focus out");
+
+ e = (Ecore_WinCE_Event_Window_Focus_Out *)calloc(1, sizeof(Ecore_WinCE_Event_Window_Focus_Out));
+ if (!e) return;
+
+ window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+ if (window->suspend)
+ window->suspend(window->backend);
+
+ e->window = window;
+
+ e->time = _ecore_wince_event_last_time;
+ _ecore_wince_event_last_time = e->time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_expose(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Damage *e;
+
+ INF("window expose");
+
+ e = (Ecore_WinCE_Event_Window_Damage *)calloc(1, sizeof(Ecore_WinCE_Event_Window_Damage));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+
+ e->x = msg->update.left;
+ e->y = msg->update.top;
+ e->width = msg->update.right - msg->update.left;
+ e->height = msg->update.bottom - msg->update.top;
+ INF("window expose size: %dx%d", e->width, e->height);
+
+ e->time = _ecore_wince_event_last_time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_create_notify(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Create *e;
+
+ INF("window create notify");
+
+ e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Create));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+
+ e->time = _ecore_wince_event_last_time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_CREATE, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_destroy_notify(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Destroy *e;
+
+ INF("window destroy notify");
+
+ e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Destroy));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+
+ e->time = _ecore_wince_event_last_time;
+/* if (e->window == _ecore_wince_event_last_window) _ecore_wince_event_last_window = NULL; */
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_DESTROY, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_map_notify(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Show *e;
+
+ INF("window map notify");
+
+ e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Show));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+
+ e->time = _ecore_wince_event_last_time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_SHOW, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_unmap_notify(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Hide *e;
+
+ INF("window unmap notify");
+
+ e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Hide));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+
+ e->time = _ecore_wince_event_last_time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_HIDE, e, NULL, NULL);
+}
+
+void
+_ecore_wince_event_handle_delete_request(Ecore_WinCE_Callback_Data *msg)
+{
+ Ecore_WinCE_Event_Window_Delete_Request *e;
+
+ INF("window delete request");
+
+ e = calloc(1, sizeof(Ecore_WinCE_Event_Window_Delete_Request));
+ if (!e) return;
+
+ e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+ if (!e->window)
+ {
+ free(e);
+ return;
+ }
+
+ e->time = _ecore_wince_event_last_time;
+
+ ecore_event_add(ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
+}
+
+
+/***** Private functions definitions *****/
+
+static void
+_ecore_wince_event_free_key_down(void *data __UNUSED__,
+ void *ev)
+{
+ Ecore_Event_Key *e;
+
+ e = ev;
+ if (e->keyname) free((char *)e->keyname);
+ if (e->key) free((char *)e->key);
+ if (e->string) free((char *)e->string);
+ free(e);
+}
+
+static void
+_ecore_wince_event_free_key_up(void *data __UNUSED__,
+ void *ev)
+{
+ Ecore_Event_Key *e;
+
+ e = ev;
+ if (e->keyname) free((char *)e->keyname);
+ if (e->key) free((char *)e->key);
+ if (e->string) free((char *)e->string);
+ free(e);
+}
+
+static int
+_ecore_wince_event_keystroke_get(int key,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose)
+{
+ char *kn;
+ char *ks;
+ char *kc;
+
+ *keyname = NULL;
+ *keysymbol = NULL;
+ *keycompose = NULL;
+
+ switch (key)
+ {
+ /* Keystroke */
+ case VK_PRIOR:
+ kn = "Prior";
+ ks = "Prior";
+ kc = "Prior";
+ break;
+ case VK_NEXT:
+ kn = "Next";
+ ks = "Next";
+ kc = "Next";
+ break;
+ case VK_END:
+ kn = "End";
+ ks = "End";
+ kc = "End";
+ break;
+ case VK_HOME:
+ kn = "Home";
+ ks = "Home";
+ kc = "Home";
+ break;
+ case VK_LEFT:
+ kn = "Left";
+ ks = "Left";
+ kc = "Left";
+ break;
+ case VK_UP:
+ kn = "Up";
+ ks = "Up";
+ kc = "Up";
+ break;
+ case VK_RIGHT:
+ kn = "Right";
+ ks = "Right";
+ kc = "Right";
+ break;
+ case VK_DOWN:
+ kn = "Down";
+ ks = "Down";
+ kc = "Down";
+ break;
+ case VK_INSERT:
+ kn = "Insert";
+ ks = "Insert";
+ kc = "Insert";
+ break;
+ case VK_DELETE:
+ kn = "Delete";
+ ks = "Delete";
+ kc = "Delete";
+ break;
+ case VK_F1:
+ kn = "F1";
+ ks = "F1";
+ kc = "";
+ break;
+ case VK_F2:
+ kn = "F2";
+ ks = "F2";
+ kc = "";
+ break;
+ case VK_F3:
+ kn = "F3";
+ ks = "F3";
+ kc = "";
+ break;
+ case VK_F4:
+ kn = "F4";
+ ks = "F4";
+ kc = "";
+ break;
+ case VK_F5:
+ kn = "F5";
+ ks = "F5";
+ kc = "";
+ break;
+ case VK_F6:
+ kn = "F6";
+ ks = "F6";
+ kc = "";
+ break;
+ case VK_F7:
+ kn = "F7";
+ ks = "F7";
+ kc = "";
+ break;
+ case VK_F8:
+ kn = "F8";
+ ks = "F8";
+ kc = "";
+ break;
+ case VK_F9:
+ kn = "F9";
+ ks = "F9";
+ kc = "";
+ break;
+ case VK_F10:
+ kn = "F10";
+ ks = "F10";
+ kc = "";
+ break;
+ case VK_F11:
+ kn = "F11";
+ ks = "F11";
+ kc = "";
+ break;
+ case VK_F12:
+ kn = "F12";
+ ks = "F12";
+ kc = "";
+ break;
+ case VK_F13:
+ kn = "F13";
+ ks = "F13";
+ kc = "";
+ break;
+ case VK_F14:
+ kn = "F14";
+ ks = "F14";
+ kc = "";
+ break;
+ case VK_F15:
+ kn = "F15";
+ ks = "F15";
+ kc = "";
+ break;
+ case VK_F16:
+ kn = "F16";
+ ks = "F16";
+ kc = "";
+ break;
+ case VK_F17:
+ kn = "F17";
+ ks = "F17";
+ kc = "";
+ break;
+ case VK_F18:
+ kn = "F18";
+ ks = "F18";
+ kc = "";
+ break;
+ case VK_F19:
+ kn = "F19";
+ ks = "F19";
+ kc = "";
+ break;
+ case VK_F20:
+ /*
+ * VK_F20 indicates that an arrow key came from a rocker.
+ * This can safely be ignored.
+ */
+ return 0;
+ case VK_F21:
+ /*
+ * VK_F21 indicates that an arrow key came from a directional
+ * pad. This can safely be ignored.
+ */
+ return 0;
+ case VK_F22:
+ kn = "F22";
+ ks = "F22";
+ kc = "";
+ break;
+ case VK_F23:
+ /*
+ * Sent with VK_RETURN when doing an action (usually the middle
+ * button on a directional pad. This can safely be ignored.
+ */
+ return 0;
+ case VK_F24:
+ kn = "F24";
+ ks = "F24";
+ kc = "";
+ break;
+ case VK_APPS:
+ kn = "Application";
+ ks = "Application";
+ kc = "";
+ break;
+ case VK_MENU:
+ kn = "Menu";
+ ks = "Menu";
+ kc = "";
+ break;
+ default:
+ /* other non keystroke characters */
+ return 0;
+ }
+ *keyname = strdup(kn);
+ if (!*keyname) return 0;
+ *keysymbol = strdup(ks);
+ if (!*keysymbol)
+ {
+ free(*keyname);
+ *keyname = NULL;
+ return 0;
+ }
+ *keycompose = strdup(kc);
+ if (!*keycompose)
+ {
+ free(*keyname);
+ free(*keysymbol);
+ *keyname = NULL;
+ *keysymbol = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+_ecore_wince_event_char_get(int key,
+ char **keyname,
+ char **keysymbol,
+ char **keycompose)
+{
+ char kn[32];
+ char ks[32];
+ char kc[32];
+
+ *keyname = NULL;
+ *keysymbol = NULL;
+ *keycompose = NULL;
+
+ switch (key)
+ {
+ case VK_APP3:
+ case VK_BACK:
+ strncpy(kn, "BackSpace", 32);
+ strncpy(ks, "BackSpace", 32);
+ strncpy(kc, "BackSpace", 32);
+ break;
+ case VK_APP4:
+ case VK_TAB:
+ strncpy(kn, "Tab", 32);
+ strncpy(ks, "Tab", 32);
+ strncpy(kc, "Tab", 32);
+ break;
+ case VK_APP5:
+ case 0x0a:
+ /* Line feed (Shift + Enter) */
+ strncpy(kn, "LineFeed", 32);
+ strncpy(ks, "LineFeed", 32);
+ strncpy(kc, "LineFeed", 32);
+ break;
+ case VK_APP2:
+ case VK_RETURN:
+ strncpy(kn, "Return", 32);
+ strncpy(ks, "Return", 32);
+ strncpy(kc, "Return", 32);
+ break;
+ case VK_APP1:
+ case VK_ESCAPE:
+ strncpy(kn, "Escape", 32);
+ strncpy(ks, "Escape", 32);
+ strncpy(kc, "Escape", 32);
+ break;
+ default:
+ /* displayable characters */
+ printf (" * key : %d\n", key);
+ kn[0] = (TCHAR)key;
+ kn[1] = '\0';
+ ks[0] = (TCHAR)key;
+ ks[1] = '\0';
+ kc[0] = (TCHAR)key;
+ kc[1] = '\0';
+ break;
+ }
+ *keyname = strdup(kn);
+ if (!*keyname) return 0;
+ *keysymbol = strdup(ks);
+ if (!*keysymbol)
+ {
+ free(*keyname);
+ *keyname = NULL;
+ return 0;
+ }
+ *keycompose = strdup(kc);
+ if (!*keycompose)
+ {
+ free(*keyname);
+ free(*keysymbol);
+ *keyname = NULL;
+ *keysymbol = NULL;
+ return 0;
+ }
+
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef __ECORE_WINCE_PRIVATE_H__
+#define __ECORE_WINCE_PRIVATE_H__
+
+
+/* logging messages macros */
+extern int _ecore_wince_log_dom_global;
+
+#ifdef ECORE_WINCE_DEFAULT_LOG_COLOR
+#undef ECORE_WINCE_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_WINCE_DEFAULT_LOG_COLOR EINA_COLOR_LIGHTBLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_wince_log_dom_global , __VA_ARGS__)
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_wince_log_dom_global , __VA_ARGS__)
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_wince_log_dom_global , __VA_ARGS__)
+
+#define ECORE_WINCE_WINDOW_CLASS L"Ecore_WinCE_Window_Class"
+
+
+typedef struct _Ecore_WinCE_Callback_Data Ecore_WinCE_Callback_Data;
+
+struct _Ecore_WinCE_Callback_Data
+{
+ RECT update;
+ HWND window;
+ unsigned int message;
+ WPARAM window_param;
+ LPARAM data_param;
+ long time;
+ int x;
+ int y;
+};
+
+
+typedef int (*ecore_wince_suspend) (int);
+typedef int (*ecore_wince_resume) (int);
+
+
+struct _Ecore_WinCE_Window
+{
+ HWND window;
+
+ int backend;
+ ecore_wince_suspend suspend;
+ ecore_wince_resume resume;
+
+ RECT rect; /* used to go fullscreen to normal */
+
+ unsigned int pointer_is_in : 1;
+ unsigned int fullscreen : 1;
+};
+
+extern HINSTANCE _ecore_wince_instance;
+extern double _ecore_wince_double_click_time;
+extern long _ecore_wince_event_last_time;
+extern Ecore_WinCE_Window *_ecore_wince_event_last_window;
+
+
+void _ecore_wince_event_handle_key_press(Ecore_WinCE_Callback_Data *msg, int is_keystroke);
+void _ecore_wince_event_handle_key_release(Ecore_WinCE_Callback_Data *msg, int is_keystroke);
+void _ecore_wince_event_handle_button_press(Ecore_WinCE_Callback_Data *msg, int button);
+void _ecore_wince_event_handle_button_release(Ecore_WinCE_Callback_Data *msg, int button);
+void _ecore_wince_event_handle_motion_notify(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_enter_notify(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_leave_notify(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_focus_in(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_focus_out(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_expose(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_create_notify(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_destroy_notify(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_map_notify(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_unmap_notify(Ecore_WinCE_Callback_Data *msg);
+void _ecore_wince_event_handle_delete_request(Ecore_WinCE_Callback_Data *msg);
+
+
+#endif /* __ECORE_WINCE_PRIVATE_H__ */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <Evil.h>
+#include <Eina.h>
+
+#include "Ecore_WinCE.h"
+#include "ecore_wince_private.h"
+
+
+/***** Private declarations *****/
+
+typedef BOOL (__stdcall *UnregisterFunc1Proc)(UINT, UINT);
+
+static int _ecore_wince_hardware_keys_register(HWND window);
+
+
+/***** API *****/
+
+Ecore_WinCE_Window *
+ecore_wince_window_new(Ecore_WinCE_Window *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ struct _Ecore_WinCE_Window *w;
+ HWND window;
+ RECT rect;
+
+ INF("creating window");
+
+ w = (struct _Ecore_WinCE_Window *)calloc(1, sizeof(struct _Ecore_WinCE_Window));
+ if (!w)
+ {
+ ERR("malloc() failed");
+ return NULL;
+ }
+
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+ if (!AdjustWindowRectEx(&rect, WS_CAPTION | WS_SYSMENU | WS_VISIBLE, FALSE, WS_EX_TOPMOST))
+ {
+ ERR("AdjustWindowRectEx() failed");
+ free(w);
+ return NULL;
+ }
+
+ window = CreateWindowEx(WS_EX_TOPMOST,
+ ECORE_WINCE_WINDOW_CLASS,
+ L"",
+ WS_CAPTION | WS_SYSMENU | WS_VISIBLE,
+ x, y,
+ rect.right - rect.left, rect.bottom - rect.top,
+ parent ? ((struct _Ecore_WinCE_Window *)parent)->window : NULL,
+ NULL, _ecore_wince_instance, NULL);
+ if (!window)
+ {
+ ERR("CreateWindowEx() failed");
+ free(w);
+ return NULL;
+ }
+
+ if (!_ecore_wince_hardware_keys_register(window))
+ {
+ ERR("_ecore_wince_hardware_keys_register() failed");
+ DestroyWindow(window);
+ free(w);
+ return NULL;
+ }
+
+ w->window = window;
+
+ SetLastError(0);
+ if (!SetWindowLong(window, GWL_USERDATA, (LONG)w) && (GetLastError() != 0))
+ {
+ ERR("SetWindowLong() failed");
+ DestroyWindow(window);
+ free(w);
+ return NULL;
+ }
+
+ w->pointer_is_in = 0;
+
+ return w;
+}
+
+void
+ecore_wince_window_free(Ecore_WinCE_Window *window)
+{
+ if (!window) return;
+
+ INF("destroying window");
+
+ DestroyWindow(((struct _Ecore_WinCE_Window *)window)->window);
+ free(window);
+}
+
+void *
+ecore_wince_window_hwnd_get(Ecore_WinCE_Window *window)
+{
+ if (!window)
+ return NULL;
+
+ return ((struct _Ecore_WinCE_Window *)window)->window;
+}
+
+void
+ecore_wince_window_move(Ecore_WinCE_Window *window,
+ int x,
+ int y)
+{
+ RECT rect;
+ HWND w;
+
+ if (!window || ((struct _Ecore_WinCE_Window *)window)->fullscreen)
+ return;
+
+ INF("moving window (%dx%d)", x, y);
+
+ w = ((struct _Ecore_WinCE_Window *)window)->window;
+ if (!GetWindowRect(w, &rect))
+ {
+ ERR("GetWindowRect() failed");
+ return;
+ }
+
+ if (!MoveWindow(w, x, y,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+}
+
+void
+ecore_wince_window_resize(Ecore_WinCE_Window *window,
+ int width,
+ int height)
+{
+ RECT rect;
+ struct _Ecore_WinCE_Window *w;
+ DWORD style;
+ DWORD exstyle;
+ int x;
+ int y;
+
+ if (!window || ((struct _Ecore_WinCE_Window *)window)->fullscreen)
+ return;
+
+ INF("resizing window (%dx%d)", width, height);
+
+ w = (struct _Ecore_WinCE_Window *)window;
+ if (!GetWindowRect(w->window, &rect))
+ {
+ ERR("GetWindowRect() failed");
+ return;
+ }
+
+ x = rect.left;
+ y = rect.top;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+ if (!(style = GetWindowLong(w->window, GWL_STYLE)))
+ {
+ ERR("GetWindowLong() failed");
+ return;
+ }
+ if (!(exstyle = GetWindowLong(w->window, GWL_EXSTYLE)))
+ {
+ ERR("GetWindowLong() failed");
+ return;
+ }
+ if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle))
+ {
+ ERR("AdjustWindowRectEx() failed");
+ return;
+ }
+
+ if (!MoveWindow(w->window, x, y,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ FALSE))
+ {
+ ERR("MoveWindow() failed");
+ }
+}
+
+void
+ecore_wince_window_move_resize(Ecore_WinCE_Window *window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ RECT rect;
+ struct _Ecore_WinCE_Window *w;
+ DWORD style;
+ DWORD exstyle;
+
+ if (!window || ((struct _Ecore_WinCE_Window *)window)->fullscreen)
+ return;
+
+ INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height);
+
+ w = ((struct _Ecore_WinCE_Window *)window);
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+ if (!(style = GetWindowLong(w->window, GWL_STYLE)))
+ {
+ ERR("GetWindowLong() failed");
+ return;
+ }
+ if (!(exstyle = GetWindowLong(w->window, GWL_EXSTYLE)))
+ {
+ ERR("GetWindowLong() failed");
+ return;
+ }
+ if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle))
+ {
+ ERR("AdjustWindowRectEx() failed");
+ return;
+ }
+
+ if (!MoveWindow(w->window, x, y,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ TRUE))
+ {
+ ERR("MoveWindow() failed");
+ }
+}
+
+void
+ecore_wince_window_show(Ecore_WinCE_Window *window)
+{
+ if (!window) return;
+
+ INF("showing window");
+
+ if (!ShowWindow(((struct _Ecore_WinCE_Window *)window)->window, SW_SHOWNORMAL))
+ {
+ ERR("ShowWindow() failed");
+ return;
+ }
+ if (!UpdateWindow(((struct _Ecore_WinCE_Window *)window)->window))
+ {
+ ERR("UpdateWindow() failed");
+ }
+ if (!SendMessage(((struct _Ecore_WinCE_Window *)window)->window, WM_SHOWWINDOW, 1, 0))
+ {
+ ERR("SendMessage() failed");
+ }
+}
+
+void
+ecore_wince_window_hide(Ecore_WinCE_Window *window)
+{
+ if (!window) return;
+
+ INF("hiding window");
+
+ if (!ShowWindow(((struct _Ecore_WinCE_Window *)window)->window, SW_HIDE))
+ {
+ ERR("ShowWindow() failed");
+ return;
+ }
+ if (!SendMessage(((struct _Ecore_WinCE_Window *)window)->window, WM_SHOWWINDOW, 0, 0))
+ {
+ ERR("SendMessage() failed");
+ }
+}
+
+void
+ecore_wince_window_title_set(Ecore_WinCE_Window *window,
+ const char *title)
+{
+ wchar_t *wtitle;
+
+ if (!window) return;
+
+ if (!title || !title[0]) return;
+
+ INF("setting window title");
+
+ wtitle = evil_char_to_wchar(title);
+ if (!wtitle) return;
+
+ if (!SetWindowText(((struct _Ecore_WinCE_Window *)window)->window, wtitle))
+ {
+ ERR("SetWindowText() failed");
+ }
+ free(wtitle);
+}
+
+void
+ecore_wince_window_backend_set(Ecore_WinCE_Window *window, int backend)
+{
+ struct _Ecore_WinCE_Window *w;
+
+ if (!window)
+ return;
+
+ INF("setting backend");
+
+ w = (struct _Ecore_WinCE_Window *)window;
+ w->backend = backend;
+}
+
+void
+ecore_wince_window_suspend_set(Ecore_WinCE_Window *window, int (*suspend)(int))
+{
+ struct _Ecore_WinCE_Window *w;
+
+ if (!window)
+ return;
+
+ INF("setting suspend callback");
+
+ w = (struct _Ecore_WinCE_Window *)window;
+ w->suspend = suspend;
+}
+
+void
+ecore_wince_window_resume_set(Ecore_WinCE_Window *window, int (*resume)(int))
+{
+ struct _Ecore_WinCE_Window *w;
+
+ if (!window)
+ return;
+
+ INF("setting resume callback");
+
+ w = (struct _Ecore_WinCE_Window *)window;
+ w->resume = resume;
+}
+
+void
+ecore_wince_window_geometry_get(Ecore_WinCE_Window *window,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+ RECT rect;
+ int w;
+ int h;
+
+ INF("getting window geometry");
+
+ if (!window)
+ {
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = GetSystemMetrics(SM_CXSCREEN);
+ if (height) *height = GetSystemMetrics(SM_CYSCREEN);
+
+ return;
+ }
+
+ if (!GetClientRect(((struct _Ecore_WinCE_Window *)window)->window,
+ &rect))
+ {
+ ERR("GetClientRect() failed");
+
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = 0;
+ if (height) *height = 0;
+
+ return;
+ }
+
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+
+ if (!GetWindowRect(((struct _Ecore_WinCE_Window *)window)->window,
+ &rect))
+ {
+ ERR("GetWindowRect() failed");
+
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = 0;
+ if (height) *height = 0;
+
+ return;
+ }
+
+ if (x) *x = rect.left;
+ if (y) *y = rect.top;
+ if (width) *width = w;
+ if (height) *height = h;
+}
+
+void
+ecore_wince_window_size_get(Ecore_WinCE_Window *window,
+ int *width,
+ int *height)
+{
+ RECT rect;
+
+ INF("getting window size");
+
+ if (!window)
+ {
+ if (width) *width = GetSystemMetrics(SM_CXSCREEN);
+ if (height) *height = GetSystemMetrics(SM_CYSCREEN);
+
+ return;
+ }
+
+ if (!GetClientRect(((struct _Ecore_WinCE_Window *)window)->window,
+ &rect))
+ {
+ ERR("GetClientRect() failed");
+
+ if (width) *width = 0;
+ if (height) *height = 0;
+ }
+
+ if (width) *width = rect.right - rect.left;
+ if (height) *height = rect.bottom - rect.top;
+}
+
+void
+ecore_wince_window_fullscreen_set(Ecore_WinCE_Window *window,
+ int on)
+{
+ struct _Ecore_WinCE_Window *ew;
+ HWND w;
+ HWND task_bar;
+
+ if (!window) return;
+
+ ew = (struct _Ecore_WinCE_Window *)window;
+ if (((ew->fullscreen) && (on)) ||
+ ((!ew->fullscreen) && (!on)))
+ return;
+
+ INF("setting fullscreen: %s", on ? "yes" : "no");
+
+ ew->fullscreen = !!on;
+ w = ew->window;
+
+ if (on)
+ {
+ /* save the position and size of the window */
+ if (!GetWindowRect(w, &ew->rect))
+ {
+ ERR("GetWindowRect() failed");
+ return;
+ }
+
+ /* hide task bar */
+ task_bar = FindWindow(L"HHTaskBar", NULL);
+ if (!task_bar)
+ {
+ INF("FindWindow(): can not find task bar");
+ }
+ if (!ShowWindow(task_bar, SW_HIDE))
+ {
+ INF("ShowWindow(): task bar already hidden");
+ }
+ if (!EnableWindow(task_bar, FALSE))
+ {
+ INF("EnableWindow(): input already disabled");
+ }
+
+ /* style: visible + popup */
+ if (!SetWindowLong(w, GWL_STYLE, WS_POPUP | WS_VISIBLE))
+ {
+ INF("SetWindowLong() failed");
+ }
+
+ /* resize window to fit the entire screen */
+ if (!SetWindowPos(w, HWND_TOPMOST,
+ 0, 0,
+ GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED))
+ {
+ INF("SetWindowPos() failed");
+ }
+ /*
+ * It seems that SetWindowPos is not sufficient.
+ * Call MoveWindow with the correct size and force painting.
+ * Note that UpdateWindow (forcing repainting) is not sufficient
+ */
+ if (!MoveWindow(w,
+ 0, 0,
+ GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+ TRUE))
+ {
+ INF("MoveWindow() failed");
+ }
+ }
+ else
+ {
+ /* show task bar */
+ task_bar = FindWindow(L"HHTaskBar", NULL);
+ if (!task_bar)
+ {
+ INF("FindWindow(): can not find task bar");
+ }
+ if (!ShowWindow(task_bar, SW_SHOW))
+ {
+ INF("ShowWindow(): task bar already visible");
+ }
+ if (!EnableWindow(task_bar, TRUE))
+ {
+ INF("EnableWindow(): input already enabled");
+ }
+
+ /* style: visible + caption + sysmenu */
+ if (!SetWindowLong(w, GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_VISIBLE))
+ {
+ INF("SetWindowLong() failed");
+ }
+ /* restaure the position and size of the window */
+ if (!SetWindowPos(w, HWND_TOPMOST,
+ ew->rect.left,
+ ew->rect.top,
+ ew->rect.right - ew->rect.left,
+ ew->rect.bottom - ew->rect.top,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED))
+ {
+ INF("SetWindowLong() failed");
+ }
+ /*
+ * It seems that SetWindowPos is not sufficient.
+ * Call MoveWindow with the correct size and force painting.
+ * Note that UpdateWindow (forcing repainting) is not sufficient
+ */
+ if (!MoveWindow(w,
+ ew->rect.left,
+ ew->rect.top,
+ ew->rect.right - ew->rect.left,
+ ew->rect.bottom - ew->rect.top,
+ TRUE))
+ {
+ INF("MoveWindow() failed");
+ }
+ }
+}
+
+
+/***** Private functions definitions *****/
+
+static int
+_ecore_wince_hardware_keys_register(HWND window)
+{
+ HINSTANCE core_dll;
+ UnregisterFunc1Proc unregister_fct;
+ int i;
+
+ core_dll = LoadLibrary(L"coredll.dll");
+ if (!core_dll)
+ {
+ ERR("LoadLibrary() failed");
+ return 0;
+ }
+
+ unregister_fct = (UnregisterFunc1Proc)GetProcAddress(core_dll, L"UnregisterFunc1");
+ if (!unregister_fct)
+ {
+ ERR("GetProcAddress() failed");
+ FreeLibrary(core_dll);
+ return 0;
+ }
+
+ for (i = 0xc1; i <= 0xcf; i++)
+ {
+ unregister_fct(MOD_WIN, i);
+ RegisterHotKey(window, i, MOD_WIN, i);
+ }
+
+ FreeLibrary(core_dll);
+
+ return 1;
+}
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_x.la
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifndef _ECORE_X_H
+#define _ECORE_X_H
+
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif
+
+#include <sys/types.h>
+
+/**
+ * @file
+ * @brief Ecore functions for dealing with the X Windows System
+ *
+ * Ecore_X provides a wrapper and convenience functions for using the
+ * X Windows System. Function groups for this part of the library
+ * include the following:
+ * @li @ref Ecore_X_Init_Group
+ * @li @ref Ecore_X_Display_Attr_Group
+ * @li @ref Ecore_X_Flush_Group
+ */
+
+
+typedef unsigned int Ecore_X_ID;
+#ifndef _ECORE_X_WINDOW_PREDEF
+typedef Ecore_X_ID Ecore_X_Window;
+#endif
+#ifdef HAVE_ECORE_X_XCB
+typedef Ecore_X_ID Ecore_X_Visual;
+#else
+typedef void * Ecore_X_Visual;
+#endif /* HAVE_ECORE_X_XCB */
+typedef Ecore_X_ID Ecore_X_Pixmap;
+typedef Ecore_X_ID Ecore_X_Drawable;
+#ifdef HAVE_ECORE_X_XCB
+typedef Ecore_X_ID Ecore_X_GC;
+#else
+typedef void * Ecore_X_GC;
+#endif /* HAVE_ECORE_X_XCB */
+typedef Ecore_X_ID Ecore_X_Atom;
+typedef Ecore_X_ID Ecore_X_Colormap;
+typedef Ecore_X_ID Ecore_X_Time;
+typedef Ecore_X_ID Ecore_X_Cursor;
+typedef void Ecore_X_Display;
+typedef void Ecore_X_Connection;
+typedef void Ecore_X_Screen;
+typedef Ecore_X_ID Ecore_X_Sync_Counter;
+typedef Ecore_X_ID Ecore_X_Sync_Alarm;
+typedef void Ecore_X_XRegion;
+
+typedef Ecore_X_ID Ecore_X_Randr_Output;
+typedef Ecore_X_ID Ecore_X_Randr_Crtc;
+typedef Ecore_X_ID Ecore_X_Randr_Mode;
+typedef unsigned short Ecore_X_Randr_Size_ID;
+
+typedef Ecore_X_ID Ecore_X_Device;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _Ecore_X_Rectangle {
+ int x, y;
+ unsigned int width, height;
+} Ecore_X_Rectangle;
+
+typedef struct _Ecore_X_Icon {
+ unsigned int width, height;
+ unsigned int *data;
+} Ecore_X_Icon;
+
+typedef enum _Ecore_X_GC_Value_Mask {
+ ECORE_X_GC_VALUE_MASK_FUNCTION = (1L << 0),
+ ECORE_X_GC_VALUE_MASK_PLANE_MASK = (1L << 1),
+ ECORE_X_GC_VALUE_MASK_FOREGROUND = (1L << 2),
+ ECORE_X_GC_VALUE_MASK_BACKGROUND = (1L << 3),
+ ECORE_X_GC_VALUE_MASK_LINE_WIDTH = (1L << 4),
+ ECORE_X_GC_VALUE_MASK_LINE_STYLE = (1L << 5),
+ ECORE_X_GC_VALUE_MASK_CAP_STYLE = (1L << 6),
+ ECORE_X_GC_VALUE_MASK_JOIN_STYLE = (1L << 7),
+ ECORE_X_GC_VALUE_MASK_FILL_STYLE = (1L << 8),
+ ECORE_X_GC_VALUE_MASK_FILL_RULE = (1L << 9),
+ ECORE_X_GC_VALUE_MASK_TILE = (1L << 10),
+ ECORE_X_GC_VALUE_MASK_STIPPLE = (1L << 11),
+ ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X = (1L << 12),
+ ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y = (1L << 13),
+ ECORE_X_GC_VALUE_MASK_FONT = (1L << 14),
+ ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE = (1L << 15),
+ ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES = (1L << 16),
+ ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X = (1L << 17),
+ ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y = (1L << 18),
+ ECORE_X_GC_VALUE_MASK_CLIP_MASK = (1L << 19),
+ ECORE_X_GC_VALUE_MASK_DASH_OFFSET = (1L << 20),
+ ECORE_X_GC_VALUE_MASK_DASH_LIST = (1L << 21),
+ ECORE_X_GC_VALUE_MASK_ARC_MODE = (1L << 22)
+} Ecore_X_GC_Value_Mask;
+
+typedef enum _Ecore_X_Composite_Update_Type {
+ ECORE_X_COMPOSITE_UPDATE_AUTOMATIC,
+ ECORE_X_COMPOSITE_UPDATE_MANUAL
+} Ecore_X_Composite_Update_Type;
+
+typedef enum _Ecore_X_Window_State {
+ /* Unknown state */
+ ECORE_X_WINDOW_STATE_UNKNOWN = 0,
+ /** The window is iconified. */
+ ECORE_X_WINDOW_STATE_ICONIFIED,
+ /** The window is a modal dialog box. */
+ ECORE_X_WINDOW_STATE_MODAL,
+ /** The window manager should keep the window's position fixed
+ * even if the virtual desktop scrolls. */
+ ECORE_X_WINDOW_STATE_STICKY,
+ /** The window has the maximum vertical size. */
+ ECORE_X_WINDOW_STATE_MAXIMIZED_VERT,
+ /** The window has the maximum horizontal size. */
+ ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ,
+ /** The window is shaded. */
+ ECORE_X_WINDOW_STATE_SHADED,
+ /** The window should not be included in the taskbar. */
+ ECORE_X_WINDOW_STATE_SKIP_TASKBAR,
+ /** The window should not be included in the pager. */
+ ECORE_X_WINDOW_STATE_SKIP_PAGER,
+ /** The window is invisible (i.e. minimized/iconified) */
+ ECORE_X_WINDOW_STATE_HIDDEN,
+ /** The window should fill the entire screen and have no
+ * window border/decorations */
+ ECORE_X_WINDOW_STATE_FULLSCREEN,
+ /* The following are not documented because they are not
+ * intended for use in applications. */
+ ECORE_X_WINDOW_STATE_ABOVE,
+ ECORE_X_WINDOW_STATE_BELOW,
+ /* FIXME: Documentation */
+ ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION
+} Ecore_X_Window_State;
+
+typedef enum _Ecore_X_Window_State_Action {
+ ECORE_X_WINDOW_STATE_ACTION_REMOVE,
+ ECORE_X_WINDOW_STATE_ACTION_ADD,
+ ECORE_X_WINDOW_STATE_ACTION_TOGGLE
+} Ecore_X_Window_State_Action;
+
+typedef enum _Ecore_X_Window_Stack_Mode {
+ ECORE_X_WINDOW_STACK_ABOVE = 0,
+ ECORE_X_WINDOW_STACK_BELOW = 1,
+ ECORE_X_WINDOW_STACK_TOP_IF = 2,
+ ECORE_X_WINDOW_STACK_BOTTOM_IF = 3,
+ ECORE_X_WINDOW_STACK_OPPOSITE = 4
+} Ecore_X_Window_Stack_Mode;
+
+typedef enum _Ecore_X_Randr_Rotation {
+ ECORE_X_RANDR_ROT_0 = (1 << 0),
+ ECORE_X_RANDR_ROT_90 = (1 << 1),
+ ECORE_X_RANDR_ROT_180 = (1 << 2),
+ ECORE_X_RANDR_ROT_270 = (1 << 3),
+ ECORE_X_RANDR_FLIP_X = (1 << 4),
+ ECORE_X_RANDR_FLIP_Y = (1 << 5)
+} Ecore_X_Randr_Rotation;
+
+typedef enum _Ecore_X_Randr_Connection {
+ ECORE_X_RANDR_CONNECTED = 0,
+ ECORE_X_RANDR_DISCONNECTED = 1,
+ ECORE_X_RANDR_UNKNOWN_CONNECTION = 2
+} Ecore_X_Randr_Connection;
+
+typedef enum _Ecore_X_Render_Subpixel_Order {
+ ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN = 0,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_HORIZONTAL_RGB = 1,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_HORIZONTAL_BGR = 2,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_VERTICAL_RGB = 3,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_VERTICAL_BGR = 4,
+ ECORE_X_RENDER_SUBPIXEL_ORDER_NONE = 5
+} Ecore_X_Render_Subpixel_Order;
+
+#define ECORE_X_SELECTION_TARGET_TARGETS "TARGETS"
+#define ECORE_X_SELECTION_TARGET_TEXT "TEXT"
+#define ECORE_X_SELECTION_TARGET_COMPOUND_TEXT "COMPOUND_TEXT"
+#define ECORE_X_SELECTION_TARGET_STRING "STRING"
+#define ECORE_X_SELECTION_TARGET_UTF8_STRING "UTF8_STRING"
+#define ECORE_X_SELECTION_TARGET_FILENAME "FILENAME"
+
+#define ECORE_X_DND_VERSION 5
+
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_COPY;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_MOVE;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_LINK;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_ASK;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE;
+
+typedef enum _Ecore_X_Selection {
+ ECORE_X_SELECTION_PRIMARY,
+ ECORE_X_SELECTION_SECONDARY,
+ ECORE_X_SELECTION_XDND,
+ ECORE_X_SELECTION_CLIPBOARD,
+ ECORE_X_SELECTION_OTHER
+} Ecore_X_Selection;
+
+typedef enum _Ecore_X_Event_Mode
+{
+ ECORE_X_EVENT_MODE_NORMAL,
+ ECORE_X_EVENT_MODE_WHILE_GRABBED,
+ ECORE_X_EVENT_MODE_GRAB,
+ ECORE_X_EVENT_MODE_UNGRAB
+} Ecore_X_Event_Mode;
+
+typedef enum _Ecore_X_Event_Detail
+{
+ ECORE_X_EVENT_DETAIL_ANCESTOR,
+ ECORE_X_EVENT_DETAIL_VIRTUAL,
+ ECORE_X_EVENT_DETAIL_INFERIOR,
+ ECORE_X_EVENT_DETAIL_NON_LINEAR,
+ ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL,
+ ECORE_X_EVENT_DETAIL_POINTER,
+ ECORE_X_EVENT_DETAIL_POINTER_ROOT,
+ ECORE_X_EVENT_DETAIL_DETAIL_NONE
+} Ecore_X_Event_Detail;
+
+typedef enum _Ecore_X_Event_Mask
+{
+ ECORE_X_EVENT_MASK_NONE = 0L,
+ ECORE_X_EVENT_MASK_KEY_DOWN = (1L << 0),
+ ECORE_X_EVENT_MASK_KEY_UP = (1L << 1),
+ ECORE_X_EVENT_MASK_MOUSE_DOWN = (1L << 2),
+ ECORE_X_EVENT_MASK_MOUSE_UP = (1L << 3),
+ ECORE_X_EVENT_MASK_MOUSE_IN = (1L << 4),
+ ECORE_X_EVENT_MASK_MOUSE_OUT = (1L << 5),
+ ECORE_X_EVENT_MASK_MOUSE_MOVE = (1L << 6),
+ ECORE_X_EVENT_MASK_WINDOW_DAMAGE = (1L << 15),
+ ECORE_X_EVENT_MASK_WINDOW_VISIBILITY = (1L << 16),
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE = (1L << 17),
+ ECORE_X_EVENT_MASK_WINDOW_RESIZE_MANAGE = (1L << 18),
+ ECORE_X_EVENT_MASK_WINDOW_MANAGE = (1L << 19),
+ ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE = (1L << 20),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE = (1L << 21),
+ ECORE_X_EVENT_MASK_WINDOW_PROPERTY = (1L << 22),
+ ECORE_X_EVENT_MASK_WINDOW_COLORMAP = (1L << 23),
+ ECORE_X_EVENT_MASK_WINDOW_GRAB = (1L << 24),
+ ECORE_X_EVENT_MASK_MOUSE_WHEEL = (1L << 29),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_IN = (1L << 30),
+ ECORE_X_EVENT_MASK_WINDOW_FOCUS_OUT = (1L << 31)
+} Ecore_X_Event_Mask;
+
+typedef enum _Ecore_X_Gravity
+{
+ ECORE_X_GRAVITY_FORGET = 0,
+ ECORE_X_GRAVITY_UNMAP = 0,
+ ECORE_X_GRAVITY_NW = 1,
+ ECORE_X_GRAVITY_N = 2,
+ ECORE_X_GRAVITY_NE = 3,
+ ECORE_X_GRAVITY_W = 4,
+ ECORE_X_GRAVITY_CENTER = 5,
+ ECORE_X_GRAVITY_E = 6,
+ ECORE_X_GRAVITY_SW = 7,
+ ECORE_X_GRAVITY_S = 8,
+ ECORE_X_GRAVITY_SE = 9,
+ ECORE_X_GRAVITY_STATIC = 10
+} Ecore_X_Gravity;
+
+/* Needed for ecore_x_region_window_shape_set */
+typedef enum _Ecore_X_Shape_Type
+{
+ ECORE_X_SHAPE_BOUNDING,
+ ECORE_X_SHAPE_CLIP
+} Ecore_X_Shape_Type;
+
+typedef struct _Ecore_X_Event_Mouse_In Ecore_X_Event_Mouse_In;
+typedef struct _Ecore_X_Event_Mouse_Out Ecore_X_Event_Mouse_Out;
+typedef struct _Ecore_X_Event_Window_Focus_In Ecore_X_Event_Window_Focus_In;
+typedef struct _Ecore_X_Event_Window_Focus_Out Ecore_X_Event_Window_Focus_Out;
+typedef struct _Ecore_X_Event_Window_Keymap Ecore_X_Event_Window_Keymap;
+typedef struct _Ecore_X_Event_Window_Damage Ecore_X_Event_Window_Damage;
+typedef struct _Ecore_X_Event_Window_Visibility_Change Ecore_X_Event_Window_Visibility_Change;
+typedef struct _Ecore_X_Event_Window_Create Ecore_X_Event_Window_Create;
+typedef struct _Ecore_X_Event_Window_Destroy Ecore_X_Event_Window_Destroy;
+typedef struct _Ecore_X_Event_Window_Hide Ecore_X_Event_Window_Hide;
+typedef struct _Ecore_X_Event_Window_Show Ecore_X_Event_Window_Show;
+typedef struct _Ecore_X_Event_Window_Show_Request Ecore_X_Event_Window_Show_Request;
+typedef struct _Ecore_X_Event_Window_Reparent Ecore_X_Event_Window_Reparent;
+typedef struct _Ecore_X_Event_Window_Configure Ecore_X_Event_Window_Configure;
+typedef struct _Ecore_X_Event_Window_Configure_Request Ecore_X_Event_Window_Configure_Request;
+typedef struct _Ecore_X_Event_Window_Gravity Ecore_X_Event_Window_Gravity;
+typedef struct _Ecore_X_Event_Window_Resize_Request Ecore_X_Event_Window_Resize_Request;
+typedef struct _Ecore_X_Event_Window_Stack Ecore_X_Event_Window_Stack;
+typedef struct _Ecore_X_Event_Window_Stack_Request Ecore_X_Event_Window_Stack_Request;
+typedef struct _Ecore_X_Event_Window_Property Ecore_X_Event_Window_Property;
+typedef struct _Ecore_X_Event_Window_Colormap Ecore_X_Event_Window_Colormap;
+typedef struct _Ecore_X_Event_Window_Mapping Ecore_X_Event_Window_Mapping;
+typedef struct _Ecore_X_Event_Selection_Clear Ecore_X_Event_Selection_Clear;
+typedef struct _Ecore_X_Event_Selection_Request Ecore_X_Event_Selection_Request;
+typedef struct _Ecore_X_Event_Selection_Notify Ecore_X_Event_Selection_Notify;
+typedef struct _Ecore_X_Selection_Data Ecore_X_Selection_Data;
+typedef struct _Ecore_X_Selection_Data_Files Ecore_X_Selection_Data_Files;
+typedef struct _Ecore_X_Selection_Data_Text Ecore_X_Selection_Data_Text;
+typedef struct _Ecore_X_Selection_Data_Targets Ecore_X_Selection_Data_Targets;
+typedef struct _Ecore_X_Event_Xdnd_Enter Ecore_X_Event_Xdnd_Enter;
+typedef struct _Ecore_X_Event_Xdnd_Position Ecore_X_Event_Xdnd_Position;
+typedef struct _Ecore_X_Event_Xdnd_Status Ecore_X_Event_Xdnd_Status;
+typedef struct _Ecore_X_Event_Xdnd_Leave Ecore_X_Event_Xdnd_Leave;
+typedef struct _Ecore_X_Event_Xdnd_Drop Ecore_X_Event_Xdnd_Drop;
+typedef struct _Ecore_X_Event_Xdnd_Finished Ecore_X_Event_Xdnd_Finished;
+typedef struct _Ecore_X_Event_Client_Message Ecore_X_Event_Client_Message;
+typedef struct _Ecore_X_Event_Window_Shape Ecore_X_Event_Window_Shape;
+typedef struct _Ecore_X_Event_Screensaver_Notify Ecore_X_Event_Screensaver_Notify;
+typedef struct _Ecore_X_Event_Sync_Counter Ecore_X_Event_Sync_Counter;
+typedef struct _Ecore_X_Event_Sync_Alarm Ecore_X_Event_Sync_Alarm;
+typedef struct _Ecore_X_Event_Screen_Change Ecore_X_Event_Screen_Change;
+typedef struct _Ecore_X_Event_Randr_Crtc_Change Ecore_X_Event_Randr_Crtc_Change;
+typedef struct _Ecore_X_Event_Randr_Output_Change Ecore_X_Event_Randr_Output_Change;
+typedef struct _Ecore_X_Event_Randr_Output_Property_Notify Ecore_X_Event_Randr_Output_Property_Notify;
+
+typedef struct _Ecore_X_Event_Window_Delete_Request Ecore_X_Event_Window_Delete_Request;
+typedef struct _Ecore_X_Event_Window_Prop_Title_Change Ecore_X_Event_Window_Prop_Title_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Visible_Title_Change Ecore_X_Event_Window_Prop_Visible_Title_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Icon_Name_Change Ecore_X_Event_Window_Prop_Icon_Name_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Client_Machine_Change Ecore_X_Event_Window_Prop_Client_Machine_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Name_Class_Change Ecore_X_Event_Window_Prop_Name_Class_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Pid_Change Ecore_X_Event_Window_Prop_Pid_Change;
+typedef struct _Ecore_X_Event_Window_Prop_Desktop_Change Ecore_X_Event_Window_Prop_Desktop_Change;
+
+typedef struct _Ecore_X_Event_Window_Move_Resize_Request Ecore_X_Event_Window_Move_Resize_Request;
+typedef struct _Ecore_X_Event_Window_State_Request Ecore_X_Event_Window_State_Request;
+typedef struct _Ecore_X_Event_Frame_Extents_Request Ecore_X_Event_Frame_Extents_Request;
+typedef struct _Ecore_X_Event_Ping Ecore_X_Event_Ping;
+typedef struct _Ecore_X_Event_Desktop_Change Ecore_X_Event_Desktop_Change;
+
+typedef struct _Ecore_X_Event_Startup_Sequence Ecore_X_Event_Startup_Sequence;
+
+typedef struct _Ecore_X_Event_Generic Ecore_X_Event_Generic;
+
+struct _Ecore_X_Event_Mouse_In
+{
+ int modifiers;
+ int x, y;
+ int same_screen;
+ struct {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window root_win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Mouse_Out
+{
+ int modifiers;
+ int x, y;
+ int same_screen;
+ struct {
+ int x, y;
+ } root;
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window root_win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Focus_In
+{
+ Ecore_X_Window win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Focus_Out
+{
+ Ecore_X_Window win;
+ Ecore_X_Event_Mode mode;
+ Ecore_X_Event_Detail detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Keymap
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Window_Damage
+{
+ Ecore_X_Window win;
+ int x, y, w, h;
+ int count;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Visibility_Change
+{
+ Ecore_X_Window win;
+ int fully_obscured;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Create
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ int override;
+ int x, y, w, h;
+ int border;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Destroy
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Hide
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Show
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Show_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Reparent
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window parent;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Configure
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window abovewin;
+ int x, y, w, h;
+ int border;
+ unsigned int override : 1;
+ unsigned int from_wm : 1;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Configure_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent_win;
+ Ecore_X_Window abovewin;
+ int x, y, w, h;
+ int border;
+ Ecore_X_Window_Stack_Mode detail;
+ unsigned long value_mask;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Gravity
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Resize_Request
+{
+ Ecore_X_Window win;
+ int w, h;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Stack
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Window_Stack_Mode detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Stack_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window parent;
+ Ecore_X_Window_Stack_Mode detail;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Property
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom atom;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Colormap
+{
+ Ecore_X_Window win;
+ Ecore_X_Colormap cmap;
+ int installed;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Selection_Clear
+{
+ Ecore_X_Window win;
+ Ecore_X_Selection selection;
+ Ecore_X_Atom atom;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Selection_Request
+{
+ Ecore_X_Window owner;
+ Ecore_X_Window requestor;
+ Ecore_X_Time time;
+ Ecore_X_Atom selection;
+ Ecore_X_Atom target;
+ Ecore_X_Atom property;
+};
+
+struct _Ecore_X_Event_Selection_Notify
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+ Ecore_X_Selection selection;
+ Ecore_X_Atom atom;
+ char *target;
+ void *data;
+};
+
+struct _Ecore_X_Selection_Data
+{
+ enum {
+ ECORE_X_SELECTION_CONTENT_NONE,
+ ECORE_X_SELECTION_CONTENT_TEXT,
+ ECORE_X_SELECTION_CONTENT_FILES,
+ ECORE_X_SELECTION_CONTENT_TARGETS,
+ ECORE_X_SELECTION_CONTENT_CUSTOM
+ } content;
+ unsigned char *data;
+ int length;
+ int format;
+
+ int (*free)(void *data);
+};
+
+struct _Ecore_X_Selection_Data_Files
+{
+ Ecore_X_Selection_Data data;
+ char **files;
+ int num_files;
+};
+
+struct _Ecore_X_Selection_Data_Text
+{
+ Ecore_X_Selection_Data data;
+ char *text;
+};
+
+struct _Ecore_X_Selection_Data_Targets
+{
+ Ecore_X_Selection_Data data;
+ char **targets;
+ int num_targets;
+};
+
+struct _Ecore_X_Event_Xdnd_Enter
+{
+ Ecore_X_Window win, source;
+
+ char **types;
+ int num_types;
+};
+
+struct _Ecore_X_Event_Xdnd_Position
+{
+ Ecore_X_Window win, source;
+ struct {
+ int x, y;
+ } position;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Event_Xdnd_Status
+{
+ Ecore_X_Window win, target;
+ int will_accept;
+ Ecore_X_Rectangle rectangle;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Event_Xdnd_Leave
+{
+ Ecore_X_Window win, source;
+};
+
+struct _Ecore_X_Event_Xdnd_Drop
+{
+ Ecore_X_Window win, source;
+ Ecore_X_Atom action;
+ struct {
+ int x, y;
+ } position;
+};
+
+struct _Ecore_X_Event_Xdnd_Finished
+{
+ Ecore_X_Window win, target;
+ int completed;
+ Ecore_X_Atom action;
+};
+
+struct _Ecore_X_Event_Client_Message
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom message_type;
+ int format;
+ union {
+ char b[20];
+ short s[10];
+ long l[5];
+ } data;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Shape
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Screensaver_Notify
+{
+ Ecore_X_Window win;
+ int on;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Sync_Counter
+{
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Sync_Alarm
+{
+ Ecore_X_Time time;
+ Ecore_X_Sync_Alarm alarm;
+};
+
+struct _Ecore_X_Event_Screen_Change
+{
+ Ecore_X_Window win;
+ Ecore_X_Window root;
+ int width;
+ int height;
+ Ecore_X_Time time;
+ Ecore_X_Time config_time;
+ int mm_width; /* in millimeters */
+ int mm_height; /* in millimeters */
+ Ecore_X_Randr_Rotation rotation;
+ Ecore_X_Render_Subpixel_Order subpixel_order;
+ Ecore_X_Randr_Size_ID size_id;
+};
+
+struct _Ecore_X_Event_Randr_Crtc_Change
+{
+ Ecore_X_Window win;
+ Ecore_X_Randr_Crtc crtc;
+ Ecore_X_Randr_Mode mode;
+ Ecore_X_Randr_Rotation rotation;
+ int x;
+ int y;
+ int width;
+ int height;
+};
+
+struct _Ecore_X_Event_Randr_Output_Change
+{
+ Ecore_X_Window win;
+ Ecore_X_Randr_Output output;
+ Ecore_X_Randr_Crtc crtc;
+ Ecore_X_Randr_Mode mode;
+ Ecore_X_Randr_Rotation rotation;
+ Ecore_X_Randr_Connection connection;
+ Ecore_X_Render_Subpixel_Order subpixel_order;
+};
+
+struct _Ecore_X_Event_Randr_Output_Property_Notify
+{
+ Ecore_X_Window win;
+ Ecore_X_Randr_Output output;
+ Ecore_X_Atom property;
+ Ecore_X_Time time;
+ int state; /* NewValue, Deleted */
+};
+
+struct _Ecore_X_Event_Window_Delete_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Title_Change
+{
+ Ecore_X_Window win;
+ char *title;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Visible_Title_Change
+{
+ Ecore_X_Window win;
+ char *title;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Icon_Name_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Client_Machine_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Name_Class_Change
+{
+ Ecore_X_Window win;
+ char *name;
+ char *clas;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Pid_Change
+{
+ Ecore_X_Window win;
+ pid_t pid;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Window_Prop_Desktop_Change
+{
+ Ecore_X_Window win;
+ long desktop;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Startup_Sequence
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Window_Move_Resize_Request
+{
+ Ecore_X_Window win;
+ int x, y;
+ int direction;
+ int button;
+ int source;
+};
+
+struct _Ecore_X_Event_Window_State_Request
+{
+ Ecore_X_Window win;
+ Ecore_X_Window_State_Action action;
+ Ecore_X_Window_State state[2];
+ int source;
+};
+
+struct _Ecore_X_Event_Frame_Extents_Request
+{
+ Ecore_X_Window win;
+};
+
+struct _Ecore_X_Event_Ping
+{
+ Ecore_X_Window win;
+ Ecore_X_Window event_win;
+ Ecore_X_Time time;
+};
+
+struct _Ecore_X_Event_Desktop_Change
+{
+ Ecore_X_Window win;
+ unsigned int desk;
+ int source;
+};
+
+struct _Ecore_X_Event_Generic
+{
+ int extension;
+ int evtype;
+ unsigned int cookie;
+ void *data;
+};
+
+EAPI extern int ECORE_X_EVENT_ANY; /**< low level event dependent on
+ backend in use, if Xlib will be XEvent,
+ if XCB will be xcb_generic_event_t.
+ @warning avoid using it.
+ */
+EAPI extern int ECORE_X_EVENT_MOUSE_IN;
+EAPI extern int ECORE_X_EVENT_MOUSE_OUT;
+EAPI extern int ECORE_X_EVENT_WINDOW_FOCUS_IN;
+EAPI extern int ECORE_X_EVENT_WINDOW_FOCUS_OUT;
+EAPI extern int ECORE_X_EVENT_WINDOW_KEYMAP;
+EAPI extern int ECORE_X_EVENT_WINDOW_DAMAGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_CREATE;
+EAPI extern int ECORE_X_EVENT_WINDOW_DESTROY;
+EAPI extern int ECORE_X_EVENT_WINDOW_HIDE;
+EAPI extern int ECORE_X_EVENT_WINDOW_SHOW;
+EAPI extern int ECORE_X_EVENT_WINDOW_SHOW_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_REPARENT;
+EAPI extern int ECORE_X_EVENT_WINDOW_CONFIGURE;
+EAPI extern int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_GRAVITY;
+EAPI extern int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_STACK;
+EAPI extern int ECORE_X_EVENT_WINDOW_STACK_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROPERTY;
+EAPI extern int ECORE_X_EVENT_WINDOW_COLORMAP;
+EAPI extern int ECORE_X_EVENT_WINDOW_MAPPING;
+EAPI extern int ECORE_X_EVENT_SELECTION_CLEAR;
+EAPI extern int ECORE_X_EVENT_SELECTION_REQUEST;
+EAPI extern int ECORE_X_EVENT_SELECTION_NOTIFY;
+EAPI extern int ECORE_X_EVENT_CLIENT_MESSAGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_SHAPE;
+EAPI extern int ECORE_X_EVENT_SCREENSAVER_NOTIFY;
+EAPI extern int ECORE_X_EVENT_SYNC_COUNTER;
+EAPI extern int ECORE_X_EVENT_SYNC_ALARM;
+EAPI extern int ECORE_X_EVENT_SCREEN_CHANGE;
+EAPI extern int ECORE_X_EVENT_RANDR_CRTC_CHANGE;
+EAPI extern int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE;
+EAPI extern int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY;
+EAPI extern int ECORE_X_EVENT_DAMAGE_NOTIFY;
+
+EAPI extern int ECORE_X_EVENT_WINDOW_DELETE_REQUEST;
+/*
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE;
+EAPI extern int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE;
+*/
+
+EAPI extern int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST;
+EAPI extern int ECORE_X_EVENT_WINDOW_STATE_REQUEST;
+EAPI extern int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST;
+EAPI extern int ECORE_X_EVENT_PING;
+EAPI extern int ECORE_X_EVENT_DESKTOP_CHANGE;
+
+EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
+EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
+EAPI extern int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
+
+EAPI extern int ECORE_X_EVENT_GENERIC;
+
+EAPI extern int ECORE_X_EVENT_XDND_ENTER;
+EAPI extern int ECORE_X_EVENT_XDND_POSITION;
+EAPI extern int ECORE_X_EVENT_XDND_STATUS;
+EAPI extern int ECORE_X_EVENT_XDND_LEAVE;
+EAPI extern int ECORE_X_EVENT_XDND_DROP;
+EAPI extern int ECORE_X_EVENT_XDND_FINISHED;
+
+EAPI extern int ECORE_X_LOCK_SCROLL;
+EAPI extern int ECORE_X_LOCK_NUM;
+EAPI extern int ECORE_X_LOCK_CAPS;
+
+typedef enum _Ecore_X_WM_Protocol
+{
+ /* If enabled the window manager will be asked to send a
+ * delete message instead of just closing (destroying) the window. */
+ ECORE_X_WM_PROTOCOL_DELETE_REQUEST,
+
+ /* If enabled the window manager will be told that the window
+ * explicitly sets input focus. */
+ ECORE_X_WM_PROTOCOL_TAKE_FOCUS,
+
+ /* If enabled the window manager can ping the window to check
+ * if it is alive. */
+ ECORE_X_NET_WM_PROTOCOL_PING,
+
+ /* If enabled the window manager can sync updating with the
+ * window (?) */
+ ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST,
+
+ /* Number of defined items */
+ ECORE_X_WM_PROTOCOL_NUM
+} Ecore_X_WM_Protocol;
+
+typedef enum _Ecore_X_Window_Input_Mode
+{
+ /* The window can never be focused */
+ ECORE_X_WINDOW_INPUT_MODE_NONE,
+
+ /* The window can be focused by the WM but doesn't focus itself */
+ ECORE_X_WINDOW_INPUT_MODE_PASSIVE,
+
+ /* The window sets the focus itself if one of its sub-windows
+ * already is focused */
+ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL,
+
+ /* The window sets the focus itself even if another window
+ * is currently focused */
+ ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL
+} Ecore_X_Window_Input_Mode;
+
+typedef enum _Ecore_X_Window_State_Hint
+{
+ /** Do not provide any state hint to the window manager */
+ ECORE_X_WINDOW_STATE_HINT_NONE = -1,
+
+ /** The window wants to remain hidden and NOT iconified */
+ ECORE_X_WINDOW_STATE_HINT_WITHDRAWN,
+
+ /** The window wants to be mapped normally */
+ ECORE_X_WINDOW_STATE_HINT_NORMAL,
+
+ /** The window wants to start in an iconified state */
+ ECORE_X_WINDOW_STATE_HINT_ICONIC
+} Ecore_X_Window_State_Hint;
+
+typedef enum _Ecore_X_Window_Type
+{
+ ECORE_X_WINDOW_TYPE_UNKNOWN = 0,
+ ECORE_X_WINDOW_TYPE_DESKTOP,
+ ECORE_X_WINDOW_TYPE_DOCK,
+ ECORE_X_WINDOW_TYPE_TOOLBAR,
+ ECORE_X_WINDOW_TYPE_MENU,
+ ECORE_X_WINDOW_TYPE_UTILITY,
+ ECORE_X_WINDOW_TYPE_SPLASH,
+ ECORE_X_WINDOW_TYPE_DIALOG,
+ ECORE_X_WINDOW_TYPE_NORMAL,
+ ECORE_X_WINDOW_TYPE_DROPDOWN_MENU,
+ ECORE_X_WINDOW_TYPE_POPUP_MENU,
+ ECORE_X_WINDOW_TYPE_TOOLTIP,
+ ECORE_X_WINDOW_TYPE_NOTIFICATION,
+ ECORE_X_WINDOW_TYPE_COMBO,
+ ECORE_X_WINDOW_TYPE_DND
+} Ecore_X_Window_Type;
+
+typedef enum _Ecore_X_Action
+{
+ ECORE_X_ACTION_MOVE,
+ ECORE_X_ACTION_RESIZE,
+ ECORE_X_ACTION_MINIMIZE,
+ ECORE_X_ACTION_SHADE,
+ ECORE_X_ACTION_STICK,
+ ECORE_X_ACTION_MAXIMIZE_HORZ,
+ ECORE_X_ACTION_MAXIMIZE_VERT,
+ ECORE_X_ACTION_FULLSCREEN,
+ ECORE_X_ACTION_CHANGE_DESKTOP,
+ ECORE_X_ACTION_CLOSE,
+ ECORE_X_ACTION_ABOVE,
+ ECORE_X_ACTION_BELOW
+} Ecore_X_Action;
+
+typedef enum _Ecore_X_Window_Configure_Mask
+{
+ ECORE_X_WINDOW_CONFIGURE_MASK_X = (1 << 0),
+ ECORE_X_WINDOW_CONFIGURE_MASK_Y = (1 << 1),
+ ECORE_X_WINDOW_CONFIGURE_MASK_W = (1 << 2),
+ ECORE_X_WINDOW_CONFIGURE_MASK_H = (1 << 3),
+ ECORE_X_WINDOW_CONFIGURE_MASK_BORDER_WIDTH = (1 << 4),
+ ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING = (1 << 5),
+ ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE = (1 << 6)
+} Ecore_X_Window_Configure_Mask;
+
+typedef enum _Ecore_X_Virtual_Keyboard_State
+{
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN = 0,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_ON,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_IP,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_URL,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD,
+ ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME
+} Ecore_X_Virtual_Keyboard_State;
+
+typedef enum _Ecore_X_Illume_Mode
+{
+ ECORE_X_ILLUME_MODE_UNKNOWN = 0,
+ ECORE_X_ILLUME_MODE_SINGLE,
+ ECORE_X_ILLUME_MODE_DUAL_TOP,
+ ECORE_X_ILLUME_MODE_DUAL_LEFT
+} Ecore_X_Illume_Mode;
+
+typedef enum _Ecore_X_Illume_Quickpanel_State
+{
+ ECORE_X_ILLUME_QUICKPANEL_STATE_UNKNOWN = 0,
+ ECORE_X_ILLUME_QUICKPANEL_STATE_OFF,
+ ECORE_X_ILLUME_QUICKPANEL_STATE_ON
+} Ecore_X_Illume_Quickpanel_State;
+
+/* Window layer constants */
+#define ECORE_X_WINDOW_LAYER_BELOW 2
+#define ECORE_X_WINDOW_LAYER_NORMAL 4
+#define ECORE_X_WINDOW_LAYER_ABOVE 6
+
+/* Property list operations */
+#define ECORE_X_PROP_LIST_REMOVE 0
+#define ECORE_X_PROP_LIST_ADD 1
+#define ECORE_X_PROP_LIST_TOGGLE 2
+
+EAPI int ecore_x_init(const char *name);
+EAPI int ecore_x_shutdown(void);
+EAPI int ecore_x_disconnect(void);
+EAPI Ecore_X_Display *ecore_x_display_get(void);
+EAPI Ecore_X_Connection *ecore_x_connection_get(void);
+EAPI int ecore_x_fd_get(void);
+EAPI Ecore_X_Screen *ecore_x_default_screen_get(void);
+EAPI void ecore_x_double_click_time_set(double t);
+EAPI double ecore_x_double_click_time_get(void);
+EAPI void ecore_x_flush(void);
+EAPI void ecore_x_sync(void);
+EAPI void ecore_x_killall(Ecore_X_Window root);
+EAPI void ecore_x_kill(Ecore_X_Window win);
+EAPI int ecore_x_dpi_get(void);
+
+EAPI Ecore_X_Time ecore_x_current_time_get(void);
+
+EAPI void ecore_x_error_handler_set(void (*func) (void *data), const void *data);
+EAPI void ecore_x_io_error_handler_set(void (*func) (void *data), const void *data);
+EAPI int ecore_x_error_request_get(void);
+EAPI int ecore_x_error_code_get(void);
+
+EAPI void ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask);
+EAPI void ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask);
+
+EAPI int ecore_x_selection_notify_send(Ecore_X_Window requestor, Ecore_X_Atom selection, Ecore_X_Atom target, Ecore_X_Atom property, Ecore_X_Time time);
+EAPI void ecore_x_selection_primary_prefetch(void);
+EAPI void ecore_x_selection_primary_fetch(void);
+EAPI int ecore_x_selection_primary_set(Ecore_X_Window w, const void *data, int size);
+EAPI int ecore_x_selection_primary_clear(void);
+EAPI void ecore_x_selection_secondary_prefetch(void);
+EAPI void ecore_x_selection_secondary_fetch(void);
+EAPI int ecore_x_selection_secondary_set(Ecore_X_Window w, const void *data, int size);
+EAPI int ecore_x_selection_secondary_clear(void);
+EAPI void ecore_x_selection_xdnd_prefetch(void);
+EAPI void ecore_x_selection_xdnd_fetch(void);
+EAPI int ecore_x_selection_xdnd_set(Ecore_X_Window w, const void *data, int size);
+EAPI int ecore_x_selection_xdnd_clear(void);
+EAPI void ecore_x_selection_clipboard_prefetch(void);
+EAPI void ecore_x_selection_clipboard_fetch(void);
+EAPI int ecore_x_selection_clipboard_set(Ecore_X_Window w, const void *data, int size);
+EAPI int ecore_x_selection_clipboard_clear(void);
+EAPI void ecore_x_selection_primary_request(Ecore_X_Window w, const char *target);
+EAPI void ecore_x_selection_secondary_request(Ecore_X_Window w, const char *target);
+EAPI void ecore_x_selection_xdnd_request(Ecore_X_Window w, const char *target);
+EAPI void ecore_x_selection_clipboard_request(Ecore_X_Window w, const char *target);
+EAPI int ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret);
+EAPI void ecore_x_selection_converter_add(char *target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret));
+EAPI void ecore_x_selection_converter_atom_add(Ecore_X_Atom target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret));
+EAPI void ecore_x_selection_converter_del(char *target);
+EAPI void ecore_x_selection_converter_atom_del(Ecore_X_Atom target);
+EAPI void ecore_x_selection_parser_add(const char *target, void *(*func)(const char *target, void *data, int size, int format));
+EAPI void ecore_x_selection_parser_del(const char *target);
+
+EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, int on);
+EAPI void ecore_x_dnd_version_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_dnd_version_get_fetch(void);
+EAPI int ecore_x_dnd_version_get(Ecore_X_Window win);
+EAPI void ecore_x_dnd_type_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_dnd_type_get_fetch(void);
+EAPI int ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type);
+EAPI void ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on);
+EAPI void ecore_x_dnd_types_set(Ecore_X_Window win, const char **types, unsigned int num_types);
+EAPI void ecore_x_dnd_actions_set(Ecore_X_Window win, Ecore_X_Atom *actions, unsigned int num_actions);
+EAPI void ecore_x_dnd_begin_prefetch(Ecore_X_Window source);
+EAPI void ecore_x_dnd_begin_fetch(void);
+EAPI int ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size);
+EAPI int ecore_x_dnd_drop(void);
+EAPI void ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action);
+EAPI void ecore_x_dnd_send_finished(void);
+EAPI void ecore_x_dnd_source_action_set(Ecore_X_Atom action);
+EAPI Ecore_X_Atom ecore_x_dnd_source_action_get(void);
+
+EAPI Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI int ecore_x_window_argb_get(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_window_manager_argb_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_argb_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_override_argb_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI Ecore_X_Window ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h);
+EAPI void ecore_x_window_configure(Ecore_X_Window win,
+ Ecore_X_Window_Configure_Mask mask,
+ int x, int y, int w, int h,
+ int border_width,
+ Ecore_X_Window sibling,
+ int stack_mode);
+EAPI void ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor c);
+EAPI void ecore_x_window_free(Ecore_X_Window win);
+EAPI void ecore_x_window_ignore_set(Ecore_X_Window win, int ignore);
+EAPI Ecore_X_Window *ecore_x_window_ignore_list(int *num);
+
+EAPI void ecore_x_window_delete_request_send(Ecore_X_Window win);
+EAPI void ecore_x_window_show(Ecore_X_Window win);
+EAPI void ecore_x_window_hide(Ecore_X_Window win);
+EAPI void ecore_x_window_move(Ecore_X_Window win, int x, int y);
+EAPI void ecore_x_window_resize(Ecore_X_Window win, int w, int h);
+EAPI void ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_focus(Ecore_X_Window win);
+EAPI void ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_get_input_focus_prefetch(void);
+EAPI void ecore_x_get_input_focus_fetch(void);
+EAPI Ecore_X_Window ecore_x_window_focus_get(void);
+EAPI void ecore_x_window_raise(Ecore_X_Window win);
+EAPI void ecore_x_window_lower(Ecore_X_Window win);
+EAPI void ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y);
+EAPI void ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h);
+EAPI void ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_window_border_width_get(Ecore_X_Window win);
+EAPI void ecore_x_window_border_width_set(Ecore_X_Window win, int width);
+EAPI int ecore_x_window_depth_get(Ecore_X_Window win);
+EAPI void ecore_x_window_cursor_show(Ecore_X_Window win, int show);
+EAPI void ecore_x_window_defaults_set(Ecore_X_Window win);
+EAPI int ecore_x_window_visible_get(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base, int x, int y, Ecore_X_Window *skip, int skip_num);
+EAPI Ecore_X_Window ecore_x_window_shadow_parent_get(Ecore_X_Window root, Ecore_X_Window win);
+EAPI void ecore_x_window_shadow_tree_flush(void);
+EAPI Ecore_X_Window ecore_x_window_root_get(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_window_at_xy_get(int x, int y);
+EAPI Ecore_X_Window ecore_x_window_at_xy_with_skip_get(int x, int y, Ecore_X_Window *skip, int skip_num);
+EAPI Ecore_X_Window ecore_x_window_at_xy_begin_get(Ecore_X_Window begin, int x, int y);
+EAPI void ecore_x_query_tree_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_query_tree_fetch(void);
+EAPI Ecore_X_Window ecore_x_window_parent_get(Ecore_X_Window win);
+
+EAPI void ecore_x_window_background_color_set(Ecore_X_Window win,
+ unsigned short r,
+ unsigned short g,
+ unsigned short b);
+EAPI void ecore_x_window_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity grav);
+EAPI void ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
+ Ecore_X_Gravity grav);
+EAPI void ecore_x_window_pixmap_set(Ecore_X_Window win,
+ Ecore_X_Pixmap pmap);
+EAPI void ecore_x_window_area_clear(Ecore_X_Window win,
+ int x, int y, int w, int h);
+EAPI void ecore_x_window_area_expose(Ecore_X_Window win,
+ int x, int y, int w, int h);
+EAPI void ecore_x_window_override_set(Ecore_X_Window win, int override);
+
+EAPI void ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int num);
+EAPI void ecore_x_window_prop_card32_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom);
+EAPI void ecore_x_window_prop_card32_get_fetch(void);
+EAPI int ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int len);
+EAPI int ecore_x_window_prop_card32_list_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ unsigned int **plst);
+
+EAPI void ecore_x_window_prop_xid_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID * lst,
+ unsigned int num);
+EAPI void ecore_x_window_prop_xid_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type);
+EAPI void ecore_x_window_prop_xid_get_fetch(void);
+EAPI int ecore_x_window_prop_xid_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID * lst,
+ unsigned int len);
+EAPI int ecore_x_window_prop_xid_list_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID ** plst);
+EAPI void ecore_x_window_prop_xid_list_change(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID item,
+ int op);
+EAPI void ecore_x_window_prop_atom_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom * val,
+ unsigned int num);
+EAPI void ecore_x_window_prop_atom_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom);
+EAPI void ecore_x_window_prop_atom_get_fetch(void);
+EAPI int ecore_x_window_prop_atom_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom * val,
+ unsigned int len);
+EAPI int ecore_x_window_prop_atom_list_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom ** plst);
+EAPI void ecore_x_window_prop_atom_list_change(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom item,
+ int op);
+EAPI void ecore_x_window_prop_window_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window * val,
+ unsigned int num);
+EAPI void ecore_x_window_prop_window_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom);
+EAPI void ecore_x_window_prop_window_get_fetch(void);
+EAPI int ecore_x_window_prop_window_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window * val,
+ unsigned int len);
+EAPI int ecore_x_window_prop_window_list_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window ** plst);
+
+EAPI Ecore_X_Atom ecore_x_window_prop_any_type(void);
+EAPI void ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Atom format, int size, void *data, int number);
+EAPI void ecore_x_window_prop_property_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom property,
+ Ecore_X_Atom type);
+EAPI void ecore_x_window_prop_property_get_fetch(void);
+EAPI int ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, unsigned char **data, int *num);
+EAPI void ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property);
+EAPI void ecore_x_window_prop_list_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_window_prop_list_fetch(void);
+EAPI Ecore_X_Atom *ecore_x_window_prop_list(Ecore_X_Window win, int *num_ret);
+EAPI void ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str);
+EAPI void ecore_x_window_prop_string_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom type);
+EAPI void ecore_x_window_prop_string_get_fetch(void);
+EAPI char *ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type);
+EAPI int ecore_x_window_prop_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol);
+EAPI Ecore_X_WM_Protocol *ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret);
+
+EAPI void ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask);
+EAPI void ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win);
+EAPI void ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win);
+EAPI void ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y);
+EAPI void ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_window_shape_rectangles_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_window_shape_rectangles_get_fetch(void);
+EAPI Ecore_X_Rectangle *ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret);
+EAPI void ecore_x_window_shape_events_select(Ecore_X_Window win, int on);
+EAPI void ecore_x_window_shape_input_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask);
+
+EAPI Ecore_X_Pixmap ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep);
+EAPI void ecore_x_pixmap_free(Ecore_X_Pixmap pmap);
+EAPI void ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, Ecore_X_Drawable dest, Ecore_X_GC gc, int sx, int sy, int w, int h, int dx, int dy);
+EAPI void ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap);
+
+EAPI Ecore_X_GC ecore_x_gc_new(Ecore_X_Drawable draw, Ecore_X_GC_Value_Mask value_mask, const unsigned int *value_list);
+EAPI void ecore_x_gc_free(Ecore_X_GC gc);
+
+EAPI int ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Event_Mask mask, long d0, long d1, long d2, long d3, long d4);
+EAPI int ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, const void *data, int len);
+EAPI int ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y);
+EAPI int ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b);
+EAPI int ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b);
+
+EAPI void ecore_x_drawable_geometry_get_prefetch(Ecore_X_Drawable drawable);
+EAPI void ecore_x_drawable_geometry_get_fetch(void);
+EAPI void ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h);
+EAPI int ecore_x_drawable_border_width_get(Ecore_X_Drawable d);
+EAPI int ecore_x_drawable_depth_get(Ecore_X_Drawable d);
+EAPI void ecore_x_drawable_rectangle_fill(Ecore_X_Drawable d, Ecore_X_GC gc, int x, int y, int width, int height);
+
+EAPI int ecore_x_cursor_color_supported_get(void);
+EAPI Ecore_X_Cursor ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y);
+EAPI void ecore_x_cursor_free(Ecore_X_Cursor c);
+EAPI Ecore_X_Cursor ecore_x_cursor_shape_get(int shape);
+EAPI void ecore_x_cursor_size_set(int size);
+EAPI int ecore_x_cursor_size_get(void);
+
+
+/* FIXME: these funcs need categorising */
+EAPI Ecore_X_Window *ecore_x_window_root_list(int *num_ret);
+EAPI Ecore_X_Window ecore_x_window_root_first_get(void);
+EAPI int ecore_x_window_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_container_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_client_manage(Ecore_X_Window win);
+EAPI void ecore_x_window_sniff(Ecore_X_Window win);
+EAPI void ecore_x_window_client_sniff(Ecore_X_Window win);
+EAPI void ecore_x_atom_get_prefetch(const char *name);
+EAPI void ecore_x_atom_get_fetch(void);
+EAPI Ecore_X_Atom ecore_x_atom_get(const char *name);
+EAPI void ecore_x_atoms_get(const char **names, int num, Ecore_X_Atom *atoms);
+EAPI void ecore_x_get_atom_name_prefetch(Ecore_X_Atom atom);
+EAPI void ecore_x_get_atom_name_fetch(void);
+EAPI char *ecore_x_atom_name_get(Ecore_X_Atom atom);
+
+
+EAPI void ecore_x_icccm_init(void);
+EAPI void ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state);
+EAPI Ecore_X_Window_State_Hint ecore_x_icccm_state_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t);
+EAPI void ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI void ecore_x_icccm_hints_set(Ecore_X_Window win,
+ int accepts_focus,
+ Ecore_X_Window_State_Hint initial_state,
+ Ecore_X_Pixmap icon_pixmap,
+ Ecore_X_Pixmap icon_mask,
+ Ecore_X_Window icon_window,
+ Ecore_X_Window window_group,
+ int is_urgent);
+EAPI int ecore_x_icccm_hints_get(Ecore_X_Window win,
+ int *accepts_focus,
+ Ecore_X_Window_State_Hint *initial_state,
+ Ecore_X_Pixmap *icon_pixmap,
+ Ecore_X_Pixmap *icon_mask,
+ Ecore_X_Window *icon_window,
+ Ecore_X_Window *window_group,
+ int *is_urgent);
+EAPI void ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
+ int request_pos,
+ Ecore_X_Gravity gravity,
+ int min_w, int min_h,
+ int max_w, int max_h,
+ int base_w, int base_h,
+ int step_x, int step_y,
+ double min_aspect,
+ double max_aspect);
+EAPI int ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
+ int *request_pos,
+ Ecore_X_Gravity *gravity,
+ int *min_w, int *min_h,
+ int *max_w, int *max_h,
+ int *base_w, int *base_h,
+ int *step_x, int *step_y,
+ double *min_aspect,
+ double *max_aspect);
+EAPI void ecore_x_icccm_title_set(Ecore_X_Window win, const char *t);
+EAPI char *ecore_x_icccm_title_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win,
+ Ecore_X_Atom *protos, int num);
+EAPI void ecore_x_icccm_protocol_set(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol,
+ int on);
+EAPI int ecore_x_icccm_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol);
+EAPI void ecore_x_icccm_name_class_set(Ecore_X_Window win,
+ const char *n,
+ const char *c);
+EAPI void ecore_x_icccm_name_class_get(Ecore_X_Window win,
+ char **n,
+ char **c);
+EAPI char *ecore_x_icccm_client_machine_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv);
+EAPI void ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv);
+EAPI char *ecore_x_icccm_icon_name_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *t);
+EAPI void ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin);
+EAPI void ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin);
+EAPI void ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwin);
+EAPI void ecore_x_icccm_transient_for_unset(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_icccm_transient_for_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role);
+EAPI char *ecore_x_icccm_window_role_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window l);
+EAPI Ecore_X_Window ecore_x_icccm_client_leader_get(Ecore_X_Window win);
+EAPI void ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root);
+
+
+typedef enum _Ecore_X_MWM_Hint_Func
+{
+ ECORE_X_MWM_HINT_FUNC_ALL = (1 << 0),
+ ECORE_X_MWM_HINT_FUNC_RESIZE = (1 << 1),
+ ECORE_X_MWM_HINT_FUNC_MOVE = (1 << 2),
+ ECORE_X_MWM_HINT_FUNC_MINIMIZE = (1 << 3),
+ ECORE_X_MWM_HINT_FUNC_MAXIMIZE = (1 << 4),
+ ECORE_X_MWM_HINT_FUNC_CLOSE = (1 << 5)
+} Ecore_X_MWM_Hint_Func;
+
+typedef enum _Ecore_X_MWM_Hint_Decor
+{
+ ECORE_X_MWM_HINT_DECOR_ALL = (1 << 0),
+ ECORE_X_MWM_HINT_DECOR_BORDER = (1 << 1),
+ ECORE_X_MWM_HINT_DECOR_RESIZEH = (1 << 2),
+ ECORE_X_MWM_HINT_DECOR_TITLE = (1 << 3),
+ ECORE_X_MWM_HINT_DECOR_MENU = (1 << 4),
+ ECORE_X_MWM_HINT_DECOR_MINIMIZE = (1 << 5),
+ ECORE_X_MWM_HINT_DECOR_MAXIMIZE = (1 << 6)
+} Ecore_X_MWM_Hint_Decor;
+
+typedef enum _Ecore_X_MWM_Hint_Input
+{
+ ECORE_X_MWM_HINT_INPUT_MODELESS = 0,
+ ECORE_X_MWM_HINT_INPUT_PRIMARY_APPLICATION_MODAL = 1,
+ ECORE_X_MWM_HINT_INPUT_SYSTEM_MODAL = 2,
+ ECORE_X_MWM_HINT_INPUT_FULL_APPLICATION_MODAL = 3
+} Ecore_X_MWM_Hint_Input;
+
+EAPI void ecore_x_mwm_hints_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_mwm_hints_get_fetch(void);
+EAPI int ecore_x_mwm_hints_get(Ecore_X_Window win,
+ Ecore_X_MWM_Hint_Func *fhint,
+ Ecore_X_MWM_Hint_Decor *dhint,
+ Ecore_X_MWM_Hint_Input *ihint);
+EAPI void ecore_x_mwm_borderless_set(Ecore_X_Window win, int borderless);
+
+/* netwm */
+EAPI void ecore_x_netwm_init(void);
+EAPI void ecore_x_netwm_shutdown(void);
+EAPI void ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check, const char *wm_name);
+EAPI void ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num);
+EAPI void ecore_x_netwm_supported_get_prefetch(Ecore_X_Window root);
+EAPI void ecore_x_netwm_supported_get_fetch(void);
+EAPI int ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num);
+EAPI void ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_roots_set(Ecore_X_Window root, Ecore_X_Window *vroots, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_names_set(Ecore_X_Window root, const char **names, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width, unsigned int height);
+EAPI void ecore_x_netwm_desk_workareas_set(Ecore_X_Window root, unsigned int *areas, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk);
+EAPI void ecore_x_netwm_desk_viewports_set(Ecore_X_Window root, unsigned int *origins, unsigned int n_desks);
+EAPI void ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation, int columns, int rows, int starting_corner);
+EAPI void ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on);
+EAPI void ecore_x_netwm_client_list_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients);
+EAPI void ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients);
+EAPI void ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win);
+EAPI void ecore_x_netwm_client_active_request(Ecore_X_Window root, Ecore_X_Window win, int type, Ecore_X_Window current_win);
+EAPI void ecore_x_netwm_name_set(Ecore_X_Window win, const char *name);
+EAPI void ecore_x_netwm_name_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_name_get_fetch(void);
+EAPI int ecore_x_netwm_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_startup_id_set(Ecore_X_Window win, const char *id);
+EAPI void ecore_x_netwm_startup_id_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_startup_id_get_fetch(void);
+EAPI int ecore_x_netwm_startup_id_get(Ecore_X_Window win, char **id);
+EAPI void ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name);
+EAPI void ecore_x_netwm_visible_name_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_visible_name_get_fetch(void);
+EAPI int ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name);
+EAPI void ecore_x_netwm_icon_name_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_icon_name_get_fetch(void);
+EAPI int ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name);
+EAPI void ecore_x_netwm_visible_icon_name_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_visible_icon_name_get_fetch(void);
+EAPI int ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name);
+EAPI void ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk);
+EAPI void ecore_x_netwm_desktop_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_desktop_get_fetch(void);
+EAPI int ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk);
+EAPI void ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right, int top, int bottom);
+EAPI void ecore_x_netwm_strut_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_strut_get_fetch(void);
+EAPI int ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom);
+EAPI void ecore_x_netwm_strut_partial_set(Ecore_X_Window win, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x);
+EAPI void ecore_x_netwm_strut_partial_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_strut_partial_get_fetch(void);
+EAPI int ecore_x_netwm_strut_partial_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom, int *left_start_y, int *left_end_y, int *right_start_y, int *right_end_y, int *top_start_x, int *top_end_x, int *bottom_start_x, int *bottom_end_x);
+EAPI void ecore_x_netwm_icons_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_icons_get_fetch(void);
+EAPI int ecore_x_netwm_icons_get(Ecore_X_Window win, Ecore_X_Icon **icon, int *num);
+EAPI void ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int width, int height);
+EAPI void ecore_x_netwm_icon_geometry_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_icon_geometry_get_fetch(void);
+EAPI int ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *width, int *height);
+EAPI void ecore_x_netwm_pid_set(Ecore_X_Window win, int pid);
+EAPI void ecore_x_netwm_pid_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_pid_get_fetch(void);
+EAPI int ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid);
+EAPI void ecore_x_netwm_handled_icons_set(Ecore_X_Window win);
+EAPI void ecore_x_netwm_handled_icons_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_handled_icons_get_fetch(void);
+EAPI int ecore_x_netwm_handled_icons_get(Ecore_X_Window win);
+EAPI void ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time);
+EAPI void ecore_x_netwm_user_time_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_user_time_get_fetch(void);
+EAPI int ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time);
+EAPI void ecore_x_netwm_window_state_set(Ecore_X_Window win, Ecore_X_Window_State *state, unsigned int num);
+EAPI void ecore_x_netwm_window_state_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_window_state_get_fetch(void);
+EAPI int ecore_x_netwm_window_state_get(Ecore_X_Window win, Ecore_X_Window_State **state, unsigned int *num);
+EAPI void ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type);
+EAPI void ecore_x_netwm_window_type_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_window_type_get_fetch(void);
+EAPI int ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type);
+EAPI int ecore_x_netwm_window_types_get(Ecore_X_Window win, Ecore_X_Window_Type **types);
+EAPI int ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action);
+EAPI void ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action *action, unsigned int num);
+EAPI void ecore_x_netwm_allowed_action_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_allowed_action_get_fetch(void);
+EAPI int ecore_x_netwm_allowed_action_get(Ecore_X_Window win, Ecore_X_Action **action, unsigned int *num);
+EAPI void ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity);
+EAPI void ecore_x_netwm_opacity_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_opacity_get_fetch(void);
+EAPI int ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity);
+EAPI void ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb);
+EAPI void ecore_x_netwm_frame_size_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_frame_size_get_fetch(void);
+EAPI int ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb);
+EAPI void ecore_x_netwm_sync_counter_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_netwm_sync_counter_get_fetch(void);
+EAPI int ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter);
+EAPI void ecore_x_netwm_ping_send(Ecore_X_Window win);
+EAPI void ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial);
+EAPI void ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root, Ecore_X_Window_State s1, Ecore_X_Window_State s2, int set);
+EAPI void ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop);
+
+
+EAPI void ecore_x_e_init(void);
+EAPI void ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb);
+EAPI void ecore_x_e_virtual_keyboard_set(Ecore_X_Window win, unsigned int is_keyboard);
+EAPI int ecore_x_e_virtual_keyboard_get(Ecore_X_Window win);
+EAPI void ecore_x_e_virtual_keyboard_state_set(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state);
+EAPI Ecore_X_Virtual_Keyboard_State ecore_x_e_virtual_keyboard_state_get(Ecore_X_Window win);
+EAPI void ecore_x_e_virtual_keyboard_state_send(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state);
+
+
+/* Illume functions */
+EAPI void ecore_x_e_illume_zone_set(Ecore_X_Window win, Ecore_X_Window zone);
+EAPI Ecore_X_Window ecore_x_e_illume_zone_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_zone_list_set(Ecore_X_Window win, Ecore_X_Window *zones, unsigned int n_zones);
+EAPI void ecore_x_e_illume_conformant_set(Ecore_X_Window win, unsigned int is_conformant);
+EAPI int ecore_x_e_illume_conformant_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_mode_set(Ecore_X_Window win, Ecore_X_Illume_Mode mode);
+EAPI Ecore_X_Illume_Mode ecore_x_e_illume_mode_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_mode_send(Ecore_X_Window win, Ecore_X_Illume_Mode mode);
+EAPI void ecore_x_e_illume_focus_back_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_focus_forward_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_focus_home_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_close_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_home_new_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_home_del_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag);
+EAPI int ecore_x_e_illume_drag_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_drag_locked_set(Ecore_X_Window win, unsigned int is_locked);
+EAPI int ecore_x_e_illume_drag_locked_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_drag_start_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_drag_end_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_indicator_geometry_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI int ecore_x_e_illume_indicator_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI void ecore_x_e_illume_softkey_geometry_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI int ecore_x_e_illume_softkey_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI void ecore_x_e_illume_keyboard_geometry_set(Ecore_X_Window win, int x, int y, int w, int h);
+EAPI int ecore_x_e_illume_keyboard_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h);
+EAPI void ecore_x_e_illume_quickpanel_set(Ecore_X_Window win, unsigned int is_quickpanel);
+EAPI int ecore_x_e_illume_quickpanel_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_state_set(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state);
+EAPI Ecore_X_Illume_Quickpanel_State ecore_x_e_illume_quickpanel_state_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_state_send(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state);
+EAPI void ecore_x_e_illume_quickpanel_state_toggle(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_priority_major_set(Ecore_X_Window win, unsigned int priority);
+EAPI int ecore_x_e_illume_quickpanel_priority_major_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_priority_minor_set(Ecore_X_Window win, unsigned int priority);
+EAPI int ecore_x_e_illume_quickpanel_priority_minor_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_zone_set(Ecore_X_Window win, unsigned int zone);
+EAPI int ecore_x_e_illume_quickpanel_zone_get(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_zone_request_send(Ecore_X_Window win);
+EAPI void ecore_x_e_illume_quickpanel_position_update_send(Ecore_X_Window win);
+
+EAPI void ecore_x_e_comp_sync_counter_set(Ecore_X_Window win, Ecore_X_Sync_Counter counter);
+EAPI Ecore_X_Sync_Counter ecore_x_e_comp_sync_counter_get(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, Eina_Bool enabled);
+EAPI Eina_Bool ecore_x_e_comp_sync_supported_get(Ecore_X_Window root);
+EAPI void ecore_x_e_comp_sync_begin_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_end_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win);
+
+EAPI void ecore_x_e_comp_flush_send(Ecore_X_Window win);
+EAPI void ecore_x_e_comp_dump_send(Ecore_X_Window win);
+
+EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter);
+EAPI int ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm);
+EAPI int ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val);
+EAPI Ecore_X_Sync_Counter ecore_x_sync_counter_new(int val);
+EAPI void ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter);
+EAPI void ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int by);
+EAPI void ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, int val);
+
+EAPI void ecore_x_xinerama_query_screens_prefetch(void);
+EAPI void ecore_x_xinerama_query_screens_fetch(void);
+EAPI int ecore_x_xinerama_screen_count_get(void);
+EAPI int ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h);
+
+EAPI int ecore_x_screensaver_event_available_get(void);
+EAPI void ecore_x_screensaver_idle_time_prefetch(void);
+EAPI void ecore_x_screensaver_idle_time_fetch(void);
+EAPI int ecore_x_screensaver_idle_time_get(void);
+EAPI void ecore_x_get_screensaver_prefetch(void);
+EAPI void ecore_x_get_screensaver_fetch(void);
+EAPI void ecore_x_screensaver_set(int timeout, int interval, int prefer_blanking, int allow_exposures);
+EAPI void ecore_x_screensaver_timeout_set(int timeout);
+EAPI int ecore_x_screensaver_timeout_get(void);
+EAPI void ecore_x_screensaver_blank_set(int timeout);
+EAPI int ecore_x_screensaver_blank_get(void);
+EAPI void ecore_x_screensaver_expose_set(int timeout);
+EAPI int ecore_x_screensaver_expose_get(void);
+EAPI void ecore_x_screensaver_interval_set(int timeout);
+EAPI int ecore_x_screensaver_interval_get(void);
+EAPI void ecore_x_screensaver_event_listen_set(int on);
+
+/* FIXME: these funcs need categorising */
+
+typedef struct _Ecore_X_Window_Attributes
+{
+ Ecore_X_Window root;
+ int x, y, w, h;
+ int border;
+ int depth;
+ unsigned char visible : 1;
+ unsigned char viewable : 1;
+ unsigned char override : 1;
+ unsigned char input_only : 1;
+ unsigned char save_under : 1;
+ struct {
+ Ecore_X_Event_Mask mine;
+ Ecore_X_Event_Mask all;
+ Ecore_X_Event_Mask no_propagate;
+ } event_mask;
+ Ecore_X_Gravity window_gravity;
+ Ecore_X_Gravity pixel_gravity;
+ Ecore_X_Colormap colormap;
+ Ecore_X_Visual visual;
+ /* FIXME: missing
+ * int map_installed;
+ * Screen *screen;
+ */
+} Ecore_X_Window_Attributes;
+
+EAPI void ecore_x_get_window_attributes_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_get_window_attributes_fetch(void);
+EAPI int ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret);
+EAPI void ecore_x_window_save_set_add(Ecore_X_Window win);
+EAPI void ecore_x_window_save_set_del(Ecore_X_Window win);
+EAPI Ecore_X_Window *ecore_x_window_children_get(Ecore_X_Window win, int *num);
+
+EAPI int ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold);
+EAPI void ecore_x_pointer_control_get_prefetch(void);
+EAPI void ecore_x_pointer_control_get_fetch(void);
+EAPI int ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold);
+EAPI int ecore_x_pointer_mapping_set(unsigned char *map, int nmap);
+EAPI void ecore_x_pointer_mapping_get_prefetch(void);
+EAPI void ecore_x_pointer_mapping_get_fetch(void);
+EAPI int ecore_x_pointer_mapping_get(unsigned char *map, int nmap);
+EAPI int ecore_x_pointer_grab(Ecore_X_Window win);
+EAPI int ecore_x_pointer_confine_grab(Ecore_X_Window win);
+EAPI void ecore_x_pointer_ungrab(void);
+EAPI int ecore_x_pointer_warp(Ecore_X_Window win, int x, int y);
+EAPI int ecore_x_keyboard_grab(Ecore_X_Window win);
+EAPI void ecore_x_keyboard_ungrab(void);
+EAPI void ecore_x_grab(void);
+EAPI void ecore_x_ungrab(void);
+EAPI void ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data);
+EAPI void ecore_x_window_button_grab(Ecore_X_Window win, int button,
+ Ecore_X_Event_Mask event_mask,
+ int mod, int any_mod);
+EAPI void ecore_x_window_button_ungrab(Ecore_X_Window win, int button,
+ int mod, int any_mod);
+EAPI void ecore_x_window_key_grab(Ecore_X_Window win, const char *key,
+ int mod, int any_mod);
+EAPI void ecore_x_window_key_ungrab(Ecore_X_Window win, const char *key,
+ int mod, int any_mod);
+
+EAPI void ecore_x_focus_reset(void);
+EAPI void ecore_x_events_allow_all(void);
+EAPI void ecore_x_pointer_last_xy_get(int *x, int *y);
+EAPI void ecore_x_pointer_xy_get_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_pointer_xy_get_fetch(void);
+EAPI void ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y);
+
+/* ecore_x_region.c */
+EAPI Ecore_X_XRegion *ecore_x_xregion_new();
+EAPI void ecore_x_xregion_free(Ecore_X_XRegion *region);
+EAPI int ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc);
+EAPI void ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y);
+EAPI int ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI int ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI int ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect);
+EAPI int ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI int ecore_x_xregion_is_empty(Ecore_X_XRegion *region);
+EAPI int ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2);
+EAPI int ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y);
+EAPI int ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect);
+
+/* ecore_x_randr.c */
+typedef struct _Ecore_X_Screen_Size Ecore_X_Screen_Size;
+struct _Ecore_X_Screen_Size
+{
+ int width, height;
+};
+
+typedef struct _Ecore_X_Screen_Refresh_Rate Ecore_X_Screen_Refresh_Rate;
+struct _Ecore_X_Screen_Refresh_Rate
+{
+ int rate;
+};
+
+EAPI int ecore_x_randr_query(void);
+EAPI int ecore_x_randr_events_select(Ecore_X_Window win, int on);
+EAPI void ecore_x_randr_get_screen_info_prefetch(Ecore_X_Window window);
+EAPI void ecore_x_randr_get_screen_info_fetch(void);
+EAPI Ecore_X_Randr_Rotation ecore_x_randr_screen_rotations_get(Ecore_X_Window root);
+EAPI Ecore_X_Randr_Rotation ecore_x_randr_screen_rotation_get(Ecore_X_Window root);
+EAPI void ecore_x_randr_screen_rotation_set(Ecore_X_Window root, Ecore_X_Randr_Rotation rot);
+EAPI Ecore_X_Screen_Size *ecore_x_randr_screen_sizes_get(Ecore_X_Window root, int *num);
+EAPI Ecore_X_Screen_Size ecore_x_randr_current_screen_size_get(Ecore_X_Window root);
+EAPI int ecore_x_randr_screen_size_set(Ecore_X_Window root, Ecore_X_Screen_Size size);
+
+EAPI Ecore_X_Screen_Refresh_Rate *ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root, int size_id, int *num);
+EAPI Ecore_X_Screen_Refresh_Rate ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root);
+
+EAPI int ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root, Ecore_X_Screen_Size size, Ecore_X_Screen_Refresh_Rate rate);
+
+/* XRender Support (horrendously incomplete) */
+typedef Ecore_X_ID Ecore_X_Picture;
+
+/* XFixes Extension Support */
+typedef Ecore_X_ID Ecore_X_Region;
+
+typedef enum _Ecore_X_Region_Type {
+ ECORE_X_REGION_BOUNDING,
+ ECORE_X_REGION_CLIP
+} Ecore_X_Region_Type;
+
+EAPI Ecore_X_Region ecore_x_region_new(Ecore_X_Rectangle *rects, int num);
+EAPI Ecore_X_Region ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap);
+EAPI Ecore_X_Region ecore_x_region_new_from_window(Ecore_X_Window win, Ecore_X_Region_Type type);
+EAPI Ecore_X_Region ecore_x_region_new_from_gc(Ecore_X_GC gc);
+EAPI Ecore_X_Region ecore_x_region_new_from_picture(Ecore_X_Picture picture);
+EAPI void ecore_x_region_free(Ecore_X_Region region);
+EAPI void ecore_x_region_set(Ecore_X_Region region, Ecore_X_Rectangle *rects, int num);
+EAPI void ecore_x_region_copy(Ecore_X_Region dest, Ecore_X_Region source);
+EAPI void ecore_x_region_combine(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2);
+EAPI void ecore_x_region_intersect(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2);
+EAPI void ecore_x_region_subtract(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2);
+EAPI void ecore_x_region_invert(Ecore_X_Region dest, Ecore_X_Rectangle *bounds, Ecore_X_Region source);
+EAPI void ecore_x_region_translate(Ecore_X_Region region, int dx, int dy);
+EAPI void ecore_x_region_extents(Ecore_X_Region dest, Ecore_X_Region source);
+EAPI void ecore_x_region_fetch_prefetch(Ecore_X_Region region);
+EAPI void ecore_x_region_fetch_fetch(void);
+EAPI Ecore_X_Rectangle *ecore_x_region_fetch(Ecore_X_Region region, int *num, Ecore_X_Rectangle *bounds);
+EAPI void ecore_x_region_expand(Ecore_X_Region dest, Ecore_X_Region source, unsigned int left, unsigned int right, unsigned int top, unsigned int bottom);
+EAPI void ecore_x_region_gc_clip_set(Ecore_X_Region region, Ecore_X_GC gc, int x_origin, int y_origin);
+EAPI void ecore_x_region_window_shape_set(Ecore_X_Region region, Ecore_X_Window win, Ecore_X_Shape_Type type, int x_offset, int y_offset);
+EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin);
+
+/* XComposite Extension Support */
+EAPI int ecore_x_composite_query(void);
+EAPI void ecore_x_composite_redirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI void ecore_x_composite_redirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI void ecore_x_composite_unredirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI void ecore_x_composite_unredirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
+EAPI Ecore_X_Pixmap ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win);
+EAPI Ecore_X_Window ecore_x_composite_render_window_enable(Ecore_X_Window root);
+EAPI void ecore_x_composite_render_window_disable(Ecore_X_Window root);
+
+/* XDamage Extension Support */
+typedef Ecore_X_ID Ecore_X_Damage;
+
+typedef enum _Ecore_X_Damage_Report_Level {
+ ECORE_X_DAMAGE_REPORT_RAW_RECTANGLES,
+ ECORE_X_DAMAGE_REPORT_DELTA_RECTANGLES,
+ ECORE_X_DAMAGE_REPORT_BOUNDING_BOX,
+ ECORE_X_DAMAGE_REPORT_NON_EMPTY
+} Ecore_X_Damage_Report_Level;
+
+struct _Ecore_X_Event_Damage {
+ Ecore_X_Damage_Report_Level level;
+ Ecore_X_Drawable drawable;
+ Ecore_X_Damage damage;
+ int more;
+ Ecore_X_Time time;
+ Ecore_X_Rectangle area;
+ Ecore_X_Rectangle geometry;
+};
+
+typedef struct _Ecore_X_Event_Damage Ecore_X_Event_Damage;
+
+EAPI int ecore_x_damage_query(void);
+EAPI Ecore_X_Damage ecore_x_damage_new(Ecore_X_Drawable d, Ecore_X_Damage_Report_Level level);
+EAPI void ecore_x_damage_free(Ecore_X_Damage damage);
+EAPI void ecore_x_damage_subtract(Ecore_X_Damage damage, Ecore_X_Region repair, Ecore_X_Region parts);
+
+EAPI int ecore_x_screen_is_composited(int screen);
+EAPI void ecore_x_screen_is_composited_set(int screen, Ecore_X_Window win);
+
+EAPI int ecore_x_dpms_query(void);
+EAPI void ecore_x_dpms_capable_get_prefetch(void);
+EAPI void ecore_x_dpms_capable_get_fetch(void);
+EAPI int ecore_x_dpms_capable_get(void);
+EAPI void ecore_x_dpms_enable_get_prefetch(void);
+EAPI void ecore_x_dpms_enable_get_fetch(void);
+EAPI int ecore_x_dpms_enabled_get(void);
+EAPI void ecore_x_dpms_enabled_set(int enabled);
+EAPI void ecore_x_dpms_timeouts_get_prefetch(void);
+EAPI void ecore_x_dpms_timeouts_get_fetch(void);
+EAPI void ecore_x_dpms_timeouts_get(unsigned int *standby, unsigned int *suspend, unsigned int *off);
+EAPI int ecore_x_dpms_timeouts_set(unsigned int standby, unsigned int suspend, unsigned int off);
+EAPI unsigned int ecore_x_dpms_timeout_standby_get(void);
+EAPI unsigned int ecore_x_dpms_timeout_suspend_get(void);
+EAPI unsigned int ecore_x_dpms_timeout_off_get(void);
+EAPI void ecore_x_dpms_timeout_standby_set(unsigned int new_timeout);
+EAPI void ecore_x_dpms_timeout_suspend_set(unsigned int new_timeout);
+EAPI void ecore_x_dpms_timeout_off_set(unsigned int new_timeout);
+
+EAPI int ecore_x_test_fake_key_down(const char *key);
+EAPI int ecore_x_test_fake_key_up(const char *key);
+EAPI int ecore_x_test_fake_key_press(const char *key);
+EAPI const char *ecore_x_keysym_string_get(int keysym);
+
+typedef struct _Ecore_X_Image Ecore_X_Image;
+
+EAPI Ecore_X_Image *ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth);
+EAPI void ecore_x_image_free(Ecore_X_Image *im);
+EAPI Eina_Bool ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw, int x, int y, int sx, int sy, int w, int h);
+EAPI void ecore_x_image_put(Ecore_X_Image *im, Ecore_X_Drawable draw, int x, int y, int sx, int sy, int w, int h);
+EAPI void *ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp);
+
+EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <Ecore_X_Atoms.h>
+#include <Ecore_X_Cursor.h>
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef _ECORE_X_ATOMS_H
+#define _ECORE_X_ATOMS_H
+
+/**
+ * @file
+ * @brief Ecore X atoms
+ */
+
+/* generic atoms */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_ATOM;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_CARDINAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_FILE_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_STRING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEXT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WINDOW;
+
+/* dnd atoms */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_MOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LINK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_PROXY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_DROP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED;
+
+/* dnd atoms that need to be exposed to the application interface */
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_COPY;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_MOVE;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_LINK;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_ASK;
+EAPI extern Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE;
+
+/* old E atom */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE;
+
+/* old Gnome atom */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER;
+
+/* ICCCM: client properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_SIZE_HINTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_HINTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CLASS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE;
+
+/* ICCCM: window manager properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_ICON_SIZE;
+
+/* ICCCM: WM_STATEproperty */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE;
+
+/* ICCCM: WM_PROTOCOLS properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW;
+
+/* ICCCM: WM_COLORMAP properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_NOTIFY;
+
+/* ICCCM: session management properties */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SM_CLIENT_ID;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE;
+
+/* Motif WM atom */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP;
+
+/* pager */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_MOVERESIZE_WINDOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_RESTACK_WINDOW;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP;
+
+/* window type */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND;
+
+/* state */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
+
+/* allowed actions */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_BELOW;
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_ID;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADOW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
+
+/* currenly E specific virtual keyboard extension, aim to submit to netwm spec
+ * later */
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME;
+
+
+/* Illume specific atoms */
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE_LIST;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CONFORMANT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_SINGLE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_BACK;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_HOME;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_NEW;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_DEL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLOSE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_START;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_END;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE;
+
+
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_COUNTER;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_BEGIN;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_END;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_CANCEL;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_FLUSH;
+EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_DUMP;
+
+#endif /* _ECORE_X_ATOMS_H */
--- /dev/null
+#ifndef _ECORE_X_CURSOR_H
+#define _ECORE_X_CURSOR_H
+
+/**
+ * @file
+ * @brief Defines the various cursor types for the X Windows system.
+ */
+
+#define ECORE_X_CURSOR_X 0
+#define ECORE_X_CURSOR_ARROW 2
+#define ECORE_X_CURSOR_BASED_ARROW_DOWN 4
+#define ECORE_X_CURSOR_UP 6
+#define ECORE_X_CURSOR_BOAT 8
+#define ECORE_X_CURSOR_BOTTOM_LEFT_CORNER 12
+#define ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER 14
+#define ECORE_X_CURSOR_BOTTOM_SIDE 16
+#define ECORE_X_CURSOR_BOTTOM_TEE 18
+#define ECORE_X_CURSOR_BOX_SPIRAL 20
+#define ECORE_X_CURSOR_CENTER_PTR 22
+#define ECORE_X_CURSOR_CIRCLE 24
+#define ECORE_X_CURSOR_CLOCK 26
+#define ECORE_X_CURSOR_COFFEE_MUG 28
+#define ECORE_X_CURSOR_CROSS 30
+#define ECORE_X_CURSOR_CROSS_REVERSE 32
+#define ECORE_X_CURSOR_CROSSHAIR 34
+#define ECORE_X_CURSOR_DIAMOND_CROSS 36
+#define ECORE_X_CURSOR_DOT 38
+#define ECORE_X_CURSOR_DOT_BOX_MASK 40
+#define ECORE_X_CURSOR_DOUBLE_ARROW 42
+#define ECORE_X_CURSOR_DRAFT_LARGE 44
+#define ECORE_X_CURSOR_DRAFT_SMALL 46
+#define ECORE_X_CURSOR_DRAPED_BOX 48
+#define ECORE_X_CURSOR_EXCHANGE 50
+#define ECORE_X_CURSOR_FLEUR 52
+#define ECORE_X_CURSOR_GOBBLER 54
+#define ECORE_X_CURSOR_GUMBY 56
+#define ECORE_X_CURSOR_HAND1 58
+#define ECORE_X_CURSOR_HAND2 60
+#define ECORE_X_CURSOR_HEART 62
+#define ECORE_X_CURSOR_ICON 64
+#define ECORE_X_CURSOR_IRON_CROSS 66
+#define ECORE_X_CURSOR_LEFT_PTR 68
+#define ECORE_X_CURSOR_LEFT_SIDE 70
+#define ECORE_X_CURSOR_LEFT_TEE 72
+#define ECORE_X_CURSOR_LEFTBUTTON 74
+#define ECORE_X_CURSOR_LL_ANGLE 76
+#define ECORE_X_CURSOR_LR_ANGLE 78
+#define ECORE_X_CURSOR_MAN 80
+#define ECORE_X_CURSOR_MIDDLEBUTTON 82
+#define ECORE_X_CURSOR_MOUSE 84
+#define ECORE_X_CURSOR_PENCIL 86
+#define ECORE_X_CURSOR_PIRATE 88
+#define ECORE_X_CURSOR_PLUS 90
+#define ECORE_X_CURSOR_QUESTION_ARROW 92
+#define ECORE_X_CURSOR_RIGHT_PTR 94
+#define ECORE_X_CURSOR_RIGHT_SIDE 96
+#define ECORE_X_CURSOR_RIGHT_TEE 98
+#define ECORE_X_CURSOR_RIGHTBUTTON 100
+#define ECORE_X_CURSOR_RTL_LOGO 102
+#define ECORE_X_CURSOR_SAILBOAT 104
+#define ECORE_X_CURSOR_SB_DOWN_ARROW 106
+#define ECORE_X_CURSOR_SB_H_DOUBLE_ARROW 108
+#define ECORE_X_CURSOR_SB_LEFT_ARROW 110
+#define ECORE_X_CURSOR_SB_RIGHT_ARROW 112
+#define ECORE_X_CURSOR_SB_UP_ARROW 114
+#define ECORE_X_CURSOR_SB_V_DOUBLE_ARROW 116
+#define ECORE_X_CURSOR_SHUTTLE 118
+#define ECORE_X_CURSOR_SIZING 120
+#define ECORE_X_CURSOR_SPIDER 122
+#define ECORE_X_CURSOR_SPRAYCAN 124
+#define ECORE_X_CURSOR_STAR 126
+#define ECORE_X_CURSOR_TARGET 128
+#define ECORE_X_CURSOR_TCROSS 130
+#define ECORE_X_CURSOR_TOP_LEFT_ARROW 132
+#define ECORE_X_CURSOR_TOP_LEFT_CORNER 134
+#define ECORE_X_CURSOR_TOP_RIGHT_CORNER 136
+#define ECORE_X_CURSOR_TOP_SIDE 138
+#define ECORE_X_CURSOR_TOP_TEE 140
+#define ECORE_X_CURSOR_TREK 142
+#define ECORE_X_CURSOR_UL_ANGLE 144
+#define ECORE_X_CURSOR_UMBRELLA 146
+#define ECORE_X_CURSOR_UR_ANGLE 148
+#define ECORE_X_CURSOR_WATCH 150
+#define ECORE_X_CURSOR_XTERM 152
+
+#endif
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_X
+
+SUBDIRS = xlib xcb
+
+if BUILD_ECORE_X_XCB
+DEP = xcb/libecore_x_xcb.la
+else
+DEP = xlib/libecore_x_xlib.la
+endif
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore \
+@EINA_CFLAGS@
+
+lib_LTLIBRARIES = libecore_x.la
+
+libecore_x_la_SOURCES =
+
+libecore_x_la_LIBADD = $(DEP) @EINA_LIBS@
+libecore_x_la_LDFLAGS = -version-info @version_info@ @ecore_x_release_info@
+libecore_x_la_DEPENDENCIES = $(DEP)
+
+include_HEADERS = \
+Ecore_X.h \
+Ecore_X_Atoms.h \
+Ecore_X_Cursor.h
+
+endif
+
+EXTRA_DIST = ecore_x_atoms_decl.h
--- /dev/null
+/* generic atoms */
+EAPI Ecore_X_Atom ECORE_X_ATOM_ATOM = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_CARDINAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_FILE_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_STRING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_TEXT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WINDOW = 0;
+
+/* dnd atoms */
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_MOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LINK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_PROXY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_DROP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED = 0;
+
+/* dnd atoms that need to be exposed to the application interface */
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_COPY = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_MOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_LINK = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_ASK = 0;
+EAPI Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE = 0;
+
+/* old E atom */
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE = 0;
+
+/* old Gnome atom */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER = 0;
+
+/* ICCCM atoms */
+
+/* ICCCM: client properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_SIZE_HINTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_HINTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CLASS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND = 0; /* obsolete */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE = 0; /* obsolete */
+
+/* ICCCM: window manager properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_ICON_SIZE = 0;
+
+/* ICCCM: WM_STATE property */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE = 0;
+
+/* ICCCM: WM_PROTOCOLS properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW = 0;
+
+/* ICCCM: WM_COLORMAP properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_NOTIFY = 0;
+
+/* ICCCM: session management properties */
+EAPI Ecore_X_Atom ECORE_X_ATOM_SM_CLIENT_ID = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE = 0;
+
+/* Motif WM atom */
+EAPI Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS = 0;
+
+/* NetWM 1.3 atoms (http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html) */
+
+/*
+ * NetWM: Root Window Properties and related messages (complete)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP = 0;
+
+/*
+ * NetWM: Other Root Window Messages (complete)
+ */
+
+/* pager */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_MOVERESIZE_WINDOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_RESTACK_WINDOW = 0;
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS = 0;
+
+/*
+ * NetWM: Application Window Properties (complete)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP = 0;
+
+/* window type */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND = 0;
+
+/* state */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION = 0;
+
+/* allowed actions */
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_ABOVE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_BELOW = 0;
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_ID = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS = 0;
+
+/*
+ * NetWM: Window Manager Protocols (complete)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER = 0;
+
+/*
+ * NetWM: Not in the spec
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADOW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_SHADE = 0;
+
+/*
+ * Startup Notification (http://standards.freedesktop.org/startup-notification-spec/startup-notification-0.1.txt)
+ */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_NET_STARTUP_INFO = 0;
+
+/* selection atoms */
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD = 0;
+
+/* currently E specific virtual keyboard extension, aim to submit to netwm spec
+ * later */
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER= 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME = 0;
+
+/* currently E specific illume extension */
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ZONE_LIST = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CONFORMANT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_SINGLE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_BACK = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_FOCUS_HOME = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLOSE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_NEW = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_HOME_DEL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_START = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_DRAG_END = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE = 0;
+
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_COUNTER = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_BEGIN = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_END = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_SYNC_CANCEL = 0;
+
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_FLUSH = 0;
+EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_DUMP = 0;
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_x_xcb.la
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_X_XCB
+
+AM_CPPFLAGS = \
+@XCB_DAMAGE_CFLAGS@ \
+@XCB_COMPOSITE_CFLAGS@ \
+@XCB_DPMS_CFLAGS@ \
+@XCB_RANDR_CFLAGS@ \
+@XCB_RENDER_CFLAGS@ \
+@XCB_SCREENSAVER_CFLAGS@ \
+@XCB_SHAPE_CFLAGS@ \
+@XCB_SYNC_CFLAGS@ \
+@XCB_XFIXES_CFLAGS@ \
+@XCB_XINERAMA_CFLAGS@ \
+@XCB_XPRINT_CFLAGS@ \
+@XCB_XTEST_CFLAGS@ \
+@XCB_CFLAGS@ \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_x \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_x \
+-I$(top_builddir)/src/lib/ecore_input \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@
+
+noinst_LTLIBRARIES = libecore_x_xcb.la
+
+libecore_x_xcb_la_SOURCES = \
+ecore_xcb_atom.c \
+ecore_xcb_cursor.c \
+ecore_xcb_damage.c \
+ecore_xcb_composite.c \
+ecore_xcb_dnd.c \
+ecore_xcb_dpms.c \
+ecore_xcb_drawable.c \
+ecore_xcb_e.c \
+ecore_xcb_events.c \
+ecore_xcb_fixes.c \
+ecore_xcb_gc.c \
+ecore_xcb_icccm.c \
+ecore_xcb_mwm.c \
+ecore_xcb_netwm.c \
+ecore_xcb_pixmap.c \
+ecore_xcb_randr.c \
+ecore_xcb_region.c \
+ecore_xcb_reply.c \
+ecore_xcb_screensaver.c \
+ecore_xcb_selection.c \
+ecore_xcb_shape.c \
+ecore_xcb_sync.c \
+ecore_xcb_window.c \
+ecore_xcb_window_prop.c \
+ecore_xcb_window_shadow.c \
+ecore_xcb_xinerama.c \
+ecore_xcb.c
+
+libecore_x_xcb_la_LIBADD = \
+@XCB_DAMAGE_LIBS@ \
+@XCB_COMPOSITE_LIBS@ \
+@XCB_DPMS_LIBS@ \
+@XCB_RANDR_LIBS@ \
+@XCB_RENDER_LIBS@ \
+@XCB_SCREENSAVER_LIBS@ \
+@XCB_SHAPE_LIBS@ \
+@XCB_SYNC_LIBS@ \
+@XCB_XFIXES_LIBS@ \
+@XCB_XINERAMA_LIBS@ \
+@XCB_XPRINT_LIBS@ \
+@XCB_XTEST_LIBS@ \
+@XCB_LIBS@ \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+@EINA_LIBS@
+
+libecore_x_xcb_la_LDFLAGS = -version-info @version_info@
+
+endif
+
+EXTRA_DIST = ecore_xcb_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include <string.h>
+
+#include <X11/keysym.h>
+
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+static int _ecore_xcb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_xcb_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_xcb_key_mask_get(xcb_keysym_t sym);
+static int _ecore_xcb_event_modifier(unsigned int state);
+
+static void *_ecore_xcb_event_filter_start(void *data);
+static int _ecore_xcb_event_filter_filter(void *data, void *loop_data,int type, void *event);
+static void _ecore_xcb_event_filter_end(void *data, void *loop_data);
+
+static Ecore_Fd_Handler *_ecore_xcb_fd_handler_handle = NULL;
+static Ecore_Event_Filter *_ecore_xcb_filter_handler = NULL;
+
+static const int XCB_EVENT_ANY = 0; /* 0 can be used as there are no event types
+ * with index 0 and 1 as they are used for
+ * errors
+ */
+
+#ifdef ECORE_XCB_DAMAGE
+static int _ecore_xcb_event_damage_id = 0;
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_RANDR
+static int _ecore_xcb_event_randr_id = 0;
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_SCREENSAVER
+static int _ecore_xcb_event_screensaver_id = 0;
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+static int _ecore_xcb_event_shape_id = 0;
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+static int _ecore_xcb_event_sync_id = 0;
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_FIXES
+static int _ecore_xcb_event_fixes_selection_id = 0;
+#endif /* ECORE_XCB_FIXES */
+
+static int _ecore_xcb_event_handlers_num = 0;
+static void (**_ecore_xcb_event_handlers) (xcb_generic_event_t * event) = NULL;
+static xcb_generic_event_t *_ecore_xcb_event_buffered = NULL;
+
+static int _ecore_xcb_init_count = 0;
+static int _ecore_xcb_grab_count = 0;
+int _ecore_x11xcb_log_dom = -1;
+
+Ecore_X_Connection *_ecore_xcb_conn = NULL;
+Ecore_X_Screen *_ecore_xcb_screen = NULL;
+double _ecore_xcb_double_click_time = 0.25;
+Ecore_X_Time _ecore_xcb_event_last_time = XCB_NONE;
+Ecore_X_Window _ecore_xcb_event_last_window = XCB_NONE;
+int16_t _ecore_xcb_event_last_root_x = 0;
+int16_t _ecore_xcb_event_last_root_y = 0;
+int _ecore_xcb_xcursor = 0;
+
+Ecore_X_Window _ecore_xcb_private_window = 0;
+
+/* FIXME - These are duplicates after making ecore atoms public */
+
+Ecore_X_Atom _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
+
+
+EAPI int ECORE_X_EVENT_ANY = 0;
+EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
+EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
+EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
+EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
+EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
+EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
+EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
+EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
+EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
+EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
+EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
+EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
+EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
+EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
+EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
+EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
+EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
+EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
+EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
+EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
+
+EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
+/*
+EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 0;
+*/
+
+EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
+EAPI int ECORE_X_EVENT_PING = 0;
+EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
+
+EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
+EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
+
+EAPI int ECORE_X_MODIFIER_SHIFT = 0;
+EAPI int ECORE_X_MODIFIER_CTRL = 0;
+EAPI int ECORE_X_MODIFIER_ALT = 0;
+EAPI int ECORE_X_MODIFIER_WIN = 0;
+
+EAPI int ECORE_X_LOCK_SCROLL = 0;
+EAPI int ECORE_X_LOCK_NUM = 0;
+EAPI int ECORE_X_LOCK_CAPS = 0;
+
+/**
+ * @defgroup Ecore_Xcb_Init_Group X Library Init and Shutdown Functions
+ *
+ * Functions that start and shut down the Ecore X Library.
+ */
+
+/**
+ * Initialize the X display connection to the given display.
+ *
+ * @param name Display target name. If @c NULL, the default display is
+ * assumed.
+ * @return The number of times the library has been initialized without
+ * being shut down. 0 is returned if an error occurs.
+ * @ingroup Ecore_Xcb_Init_Group
+ */
+EAPI int
+ecore_x_init(const char *name)
+{
+ xcb_screen_iterator_t iter;
+ int screen;
+ uint32_t max_request_length;
+ const xcb_query_extension_reply_t *reply_big_requests;
+#ifdef ECORE_XCB_DAMAGE
+ const xcb_query_extension_reply_t *reply_damage;
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_COMPOSITE
+ const xcb_query_extension_reply_t *reply_composite;
+#endif /* ECORE_XCB_COMPOSITE */
+#ifdef ECORE_XCB_DPMS
+ const xcb_query_extension_reply_t *reply_dpms;
+#endif /* ECORE_XCB_DPMS */
+#ifdef ECORE_XCB_RANDR
+ const xcb_query_extension_reply_t *reply_randr;
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_SCREENSAVER
+ const xcb_query_extension_reply_t *reply_screensaver;
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+ const xcb_query_extension_reply_t *reply_shape;
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_initialize_cookie_t cookie_sync_init;
+ xcb_sync_initialize_reply_t *reply_sync_init;
+ const xcb_query_extension_reply_t *reply_sync;
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_FIXES
+ const xcb_query_extension_reply_t *reply_xfixes;
+#endif /* ECORE_XCB_FIXES */
+#ifdef ECORE_XCB_XINERAMA
+ const xcb_query_extension_reply_t *reply_xinerama;
+#endif /* ECORE_XCB_XINERAMA */
+#ifdef ECORE_XCB_XPRINT
+ const xcb_query_extension_reply_t *reply_xprint;
+#endif /* ECORE_XCB_XPRINT */
+
+ xcb_intern_atom_cookie_t atom_cookies[ECORE_X_ATOMS_COUNT];
+
+ if (++_ecore_xcb_init_count != 1)
+ return _ecore_xcb_init_count;
+ _ecore_x11xcb_log_dom = eina_log_domain_register("EcoreXCB", ECORE_XLIB_XCB_DEFAULT_LOG_COLOR);
+ if(_ecore_x11xcb_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain the Ecore XCB module.");
+ return --_ecore_xcb_init_count;
+ }
+ _ecore_xcb_conn = xcb_connect(name, &screen);
+ if (xcb_connection_has_error(_ecore_xcb_conn)) {
+ eina_log_domain_unregister(_ecore_x11xcb_log_dom);
+ _ecore_x11xcb_log_dom = -1;
+ return --_ecore_xcb_init_count;
+ }
+ /* FIXME: no error code right now */
+ /* _ecore_xcb_error_handler_init(); */
+
+ /********************/
+ /* First round trip */
+ /********************/
+
+ /*
+ * Non blocking stuff:
+ *
+ * 1. We request the atoms
+ * 2. We Prefetch the extension data
+ *
+ */
+
+
+ /* We request the atoms (non blocking) */
+ _ecore_x_atom_init(atom_cookies);
+
+ /* We prefetch all the extension data (non blocking) */
+
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_big_requests_id);
+
+#ifdef ECORE_XCB_DAMAGE
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id);
+#endif /* ECORE_XCB_DAMAGE */
+
+#ifdef ECORE_XCB_COMPOSITE
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_composite_id);
+#endif /* ECORE_XCB_COMPOSITE */
+
+#ifdef ECORE_XCB_DPMS
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dpms_id);
+#endif /* ECORE_XCB_DPMS */
+
+#ifdef ECORE_XCB_RANDR
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id);
+#endif /* ECORE_XCB_RANDR */
+
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id);
+#endif /* ECORE_XCB_SCREENSAVER */
+
+#ifdef ECORE_XCB_SHAPE
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shape_id);
+#endif /* ECORE_XCB_SHAPE */
+
+#ifdef ECORE_XCB_SYNC
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_sync_id);
+ cookie_sync_init = xcb_sync_initialize_unchecked(_ecore_xcb_conn,
+ XCB_SYNC_MAJOR_VERSION,
+ XCB_SYNC_MINOR_VERSION);
+#endif /* ECORE_XCB_SYNC */
+
+#ifdef ECORE_XCB_FIXES
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id);
+#endif /* ECORE_XCB_FIXES */
+
+#ifdef ECORE_XCB_XINERAMA
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xinerama_id);
+#endif /* ECORE_XCB_XINERAMA */
+
+#ifdef ECORE_XCB_XPRINT
+ xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
+#endif /* ECORE_XCB_XPRINT */
+
+ /* We init some components (not related to XCB) */
+ if (!ecore_event_init())
+ goto close_connection;
+
+ _ecore_x_reply_init();
+ _ecore_x_dnd_init();
+ ecore_x_netwm_init();
+ _ecore_x_selection_init();
+
+ /* There is no LASTEvent constant in XCB */
+ /* LASTevent is equal to 35 */
+ _ecore_xcb_event_handlers_num = 35;
+
+ /* We get the default screen */
+ iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ for (; iter.rem; --screen, xcb_screen_next (&iter))
+ if (screen == 0)
+ {
+ _ecore_xcb_screen = iter.data;
+ break;
+ }
+
+ /*
+ * Blocking stuff:
+ *
+ * 1. We get the atoms
+ * 2. We ask for the extension data
+ *
+ */
+
+ /* We get the atoms (blocking) */
+ _ecore_x_atom_init_finalize(atom_cookies);
+
+ /* We then ask for the extension data (blocking) */
+ reply_big_requests = xcb_get_extension_data(_ecore_xcb_conn, &xcb_big_requests_id);
+
+#ifdef ECORE_XCB_DAMAGE
+ reply_damage = xcb_get_extension_data(_ecore_xcb_conn, &xcb_damage_id);
+ if (reply_damage)
+ _ecore_xcb_event_damage_id = reply_damage->first_event + XCB_DAMAGE_NOTIFY;
+ if (_ecore_xcb_event_damage_id >= _ecore_xcb_event_handlers_num)
+ _ecore_xcb_event_handlers_num = _ecore_xcb_event_damage_id + 1;
+#endif /* ECORE_XCB_DAMAGE */
+
+#ifdef ECORE_XCB_COMPOSITE
+ reply_composite = xcb_get_extension_data(_ecore_xcb_conn, &xcb_composite_id);
+#endif /* ECORE_XCB_COMPOSITE */
+
+#ifdef ECORE_XCB_DPMS
+ reply_dpms = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id);
+#endif /* ECORE_XCB_DPMS */
+
+#ifdef ECORE_XCB_RANDR
+ reply_randr = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id);
+ if (reply_randr)
+ _ecore_xcb_event_randr_id = reply_randr->first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY;
+ if (_ecore_xcb_event_randr_id >= _ecore_xcb_event_handlers_num)
+ _ecore_xcb_event_handlers_num = _ecore_xcb_event_randr_id + 1;
+#endif /* ECORE_XCB_RANDR */
+
+#ifdef ECORE_XCB_SCREENSAVER
+ reply_screensaver = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id);
+ if (reply_screensaver)
+ _ecore_xcb_event_screensaver_id = reply_screensaver->first_event + XCB_SCREENSAVER_NOTIFY;
+ if (_ecore_xcb_event_screensaver_id >= _ecore_xcb_event_handlers_num)
+ _ecore_xcb_event_handlers_num = _ecore_xcb_event_screensaver_id + 1;
+#endif /* ECORE_XCB_SCREENSAVER */
+
+#ifdef ECORE_XCB_SHAPE
+ reply_shape = xcb_get_extension_data(_ecore_xcb_conn, &xcb_shape_id);
+ if (reply_shape)
+ _ecore_xcb_event_shape_id = reply_shape->first_event + XCB_SHAPE_NOTIFY;
+ if (_ecore_xcb_event_shape_id >= _ecore_xcb_event_handlers_num)
+ _ecore_xcb_event_handlers_num = _ecore_xcb_event_shape_id + 1;
+#endif /* ECORE_XCB_SHAPE */
+
+#ifdef ECORE_XCB_SYNC
+ reply_sync = xcb_get_extension_data(_ecore_xcb_conn, &xcb_sync_id);
+ if (reply_sync)
+ {
+ _ecore_xcb_event_sync_id = reply_sync->first_event;
+ reply_sync_init = xcb_sync_initialize_reply(_ecore_xcb_conn,
+ cookie_sync_init, NULL);
+ if (!reply_sync_init)
+ _ecore_xcb_event_sync_id = 0;
+ else
+ free(reply_sync_init);
+ }
+ if (_ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY >= _ecore_xcb_event_handlers_num)
+ _ecore_xcb_event_handlers_num = _ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY + 1;
+#endif /* ECORE_XCB_SYNC */
+
+#ifdef ECORE_XCB_FIXES
+ reply_xfixes = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id);
+ if (reply_xfixes)
+ _ecore_xcb_event_fixes_selection_id = reply_xfixes->first_event + XCB_XFIXES_SELECTION_NOTIFY;
+ if (_ecore_xcb_event_fixes_selection_id >= _ecore_xcb_event_handlers_num)
+ _ecore_xcb_event_handlers_num = _ecore_xcb_event_fixes_selection_id + 1;
+#endif /* ECORE_XCB_FIXES */
+
+#ifdef ECORE_XCB_XINERAMA
+ reply_xinerama = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xinerama_id);
+#endif /* ECORE_XCB_XINERAMA */
+
+#ifdef ECORE_XCB_XPRINT
+ reply_xprint = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
+#endif /* ECORE_XCB_XPRINT */
+
+ /*********************/
+ /* Second round trip */
+ /*********************/
+
+ /* We ask for the QueryVersion request of the extensions */
+#ifdef ECORE_XCB_DAMAGE
+ _ecore_x_damage_init(reply_damage);
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_COMPOSITE
+ _ecore_x_composite_init(reply_composite);
+#endif /* ECORE_XCB_COMPOSITE */
+#ifdef ECORE_XCB_DPMS
+ _ecore_x_dpms_init(reply_dpms);
+#endif /* ECORE_XCB_DPMS */
+#ifdef ECORE_XCB_RANDR
+ _ecore_x_randr_init(reply_randr);
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_SCREENSAVER
+ _ecore_x_screensaver_init(reply_screensaver);
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+ _ecore_x_shape_init(reply_shape);
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+ _ecore_x_sync_init(reply_sync);
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_FIXES
+ _ecore_x_xfixes_init(reply_xfixes);
+#endif /* ECORE_XCB_FIXES */
+#ifdef ECORE_XCB_XINERAMA
+ _ecore_x_xinerama_init(reply_xinerama);
+#endif /* ECORE_XCB_XINERAMA */
+
+ /* we enable the Big Request extension if present */
+ max_request_length = xcb_get_maximum_request_length(_ecore_xcb_conn);
+
+ _ecore_xcb_event_handlers = calloc(_ecore_xcb_event_handlers_num, sizeof(void *));
+ if (!_ecore_xcb_event_handlers)
+ goto finalize_extensions;
+
+#ifdef ECORE_XCB_CURSOR
+ _ecore_xcb_xcursor = XcursorSupportsARGB(_ecore_xcb_conn);
+#endif /* ECORE_XCB_CURSOR */
+
+ _ecore_xcb_event_handlers[XCB_EVENT_ANY] = _ecore_x_event_handle_any_event;
+ _ecore_xcb_event_handlers[XCB_KEY_PRESS] = _ecore_x_event_handle_key_press;
+ _ecore_xcb_event_handlers[XCB_KEY_RELEASE] = _ecore_x_event_handle_key_release;
+ _ecore_xcb_event_handlers[XCB_BUTTON_PRESS] = _ecore_x_event_handle_button_press;
+ _ecore_xcb_event_handlers[XCB_BUTTON_RELEASE] = _ecore_x_event_handle_button_release;
+ _ecore_xcb_event_handlers[XCB_MOTION_NOTIFY] = _ecore_x_event_handle_motion_notify;
+ _ecore_xcb_event_handlers[XCB_ENTER_NOTIFY] = _ecore_x_event_handle_enter_notify;
+ _ecore_xcb_event_handlers[XCB_LEAVE_NOTIFY] = _ecore_x_event_handle_leave_notify;
+ _ecore_xcb_event_handlers[XCB_FOCUS_IN] = _ecore_x_event_handle_focus_in;
+ _ecore_xcb_event_handlers[XCB_FOCUS_OUT] = _ecore_x_event_handle_focus_out;
+ _ecore_xcb_event_handlers[XCB_KEYMAP_NOTIFY] = _ecore_x_event_handle_keymap_notify;
+ _ecore_xcb_event_handlers[XCB_EXPOSE] = _ecore_x_event_handle_expose;
+ _ecore_xcb_event_handlers[XCB_GRAPHICS_EXPOSURE] = _ecore_x_event_handle_graphics_expose;
+ _ecore_xcb_event_handlers[XCB_VISIBILITY_NOTIFY] = _ecore_x_event_handle_visibility_notify;
+ _ecore_xcb_event_handlers[XCB_CREATE_NOTIFY] = _ecore_x_event_handle_create_notify;
+ _ecore_xcb_event_handlers[XCB_DESTROY_NOTIFY] = _ecore_x_event_handle_destroy_notify;
+ _ecore_xcb_event_handlers[XCB_UNMAP_NOTIFY] = _ecore_x_event_handle_unmap_notify;
+ _ecore_xcb_event_handlers[XCB_MAP_NOTIFY] = _ecore_x_event_handle_map_notify;
+ _ecore_xcb_event_handlers[XCB_MAP_REQUEST] = _ecore_x_event_handle_map_request;
+ _ecore_xcb_event_handlers[XCB_REPARENT_NOTIFY] = _ecore_x_event_handle_reparent_notify;
+ _ecore_xcb_event_handlers[XCB_CONFIGURE_NOTIFY] = _ecore_x_event_handle_configure_notify;
+ _ecore_xcb_event_handlers[XCB_CONFIGURE_REQUEST] = _ecore_x_event_handle_configure_request;
+ _ecore_xcb_event_handlers[XCB_GRAVITY_NOTIFY] = _ecore_x_event_handle_gravity_notify;
+ _ecore_xcb_event_handlers[XCB_RESIZE_REQUEST] = _ecore_x_event_handle_resize_request;
+ _ecore_xcb_event_handlers[XCB_CIRCULATE_NOTIFY] = _ecore_x_event_handle_circulate_notify;
+ _ecore_xcb_event_handlers[XCB_CIRCULATE_REQUEST] = _ecore_x_event_handle_circulate_request;
+ _ecore_xcb_event_handlers[XCB_PROPERTY_NOTIFY] = _ecore_x_event_handle_property_notify;
+ _ecore_xcb_event_handlers[XCB_SELECTION_CLEAR] = _ecore_x_event_handle_selection_clear;
+ _ecore_xcb_event_handlers[XCB_SELECTION_REQUEST] = _ecore_x_event_handle_selection_request;
+ _ecore_xcb_event_handlers[XCB_SELECTION_NOTIFY] = _ecore_x_event_handle_selection_notify;
+ _ecore_xcb_event_handlers[XCB_COLORMAP_NOTIFY] = _ecore_x_event_handle_colormap_notify;
+ _ecore_xcb_event_handlers[XCB_CLIENT_MESSAGE] = _ecore_x_event_handle_client_message;
+ _ecore_xcb_event_handlers[XCB_MAPPING_NOTIFY] = _ecore_x_event_handle_mapping_notify;
+#ifdef ECORE_XCB_DAMAGE
+ if (_ecore_xcb_event_damage_id)
+ _ecore_xcb_event_handlers[_ecore_xcb_event_damage_id] = _ecore_x_event_handle_damage_notify;
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_RANDR
+ if (_ecore_xcb_event_randr_id)
+ _ecore_xcb_event_handlers[_ecore_xcb_event_randr_id] = _ecore_x_event_handle_randr_change;
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_SCREENSAVER
+ if (_ecore_xcb_event_screensaver_id)
+ _ecore_xcb_event_handlers[_ecore_xcb_event_screensaver_id] = _ecore_x_event_handle_screensaver_notify;
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+ if (_ecore_xcb_event_shape_id)
+ _ecore_xcb_event_handlers[_ecore_xcb_event_shape_id] = _ecore_x_event_handle_shape_change;
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+ if (_ecore_xcb_event_sync_id)
+ {
+ _ecore_xcb_event_handlers[_ecore_xcb_event_sync_id + XCB_SYNC_COUNTER_NOTIFY] =
+ _ecore_x_event_handle_sync_counter;
+ _ecore_xcb_event_handlers[_ecore_xcb_event_sync_id + XCB_SYNC_ALARM_NOTIFY] =
+ _ecore_x_event_handle_sync_alarm;
+ }
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_FIXES
+ if (_ecore_xcb_event_fixes_selection_id)
+ _ecore_xcb_event_handlers[_ecore_xcb_event_fixes_selection_id] = _ecore_x_event_handle_fixes_selection_notify;
+#endif /* ECORE_XCB_FIXES */
+
+ if (!ECORE_X_EVENT_ANY)
+ {
+ ECORE_X_EVENT_ANY = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
+ ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
+ ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
+ ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new();
+
+ ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
+ /*
+ ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new();
+ */
+
+ ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_PING = ecore_event_type_new();
+
+ ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new();
+ ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new();
+ }
+
+ /* everything has these... unless its like a pda... :) */
+ ECORE_X_MODIFIER_SHIFT = _ecore_xcb_key_mask_get(XK_Shift_L);
+ ECORE_X_MODIFIER_CTRL = _ecore_xcb_key_mask_get(XK_Control_L);
+
+ /* apple's xdarwin has no alt!!!! */
+ ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Alt_L);
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Meta_L);
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_xcb_key_mask_get(XK_Super_L);
+
+ /* the windows key... a valid modifier :) */
+ ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Super_L);
+ if (!ECORE_X_MODIFIER_WIN)
+ ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Mode_switch);
+ if (!ECORE_X_MODIFIER_WIN)
+ ECORE_X_MODIFIER_WIN = _ecore_xcb_key_mask_get(XK_Meta_L);
+
+ if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_WIN = 0;
+ if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
+ ECORE_X_MODIFIER_ALT = 0;
+
+ ECORE_X_LOCK_SCROLL = _ecore_xcb_key_mask_get(XK_Scroll_Lock);
+ ECORE_X_LOCK_NUM = _ecore_xcb_key_mask_get(XK_Num_Lock);
+ ECORE_X_LOCK_CAPS = _ecore_xcb_key_mask_get(XK_Caps_Lock);
+
+ _ecore_xcb_fd_handler_handle =
+ ecore_main_fd_handler_add(xcb_get_file_descriptor(_ecore_xcb_conn),
+ ECORE_FD_READ,
+ _ecore_xcb_fd_handler, _ecore_xcb_conn,
+ _ecore_xcb_fd_handler_buf, _ecore_xcb_conn);
+ if (!_ecore_xcb_fd_handler_handle)
+ goto free_event_handlers;
+
+ _ecore_xcb_filter_handler = ecore_event_filter_add(_ecore_xcb_event_filter_start, _ecore_xcb_event_filter_filter, _ecore_xcb_event_filter_end, NULL);
+
+ /* This is just to be anal about naming conventions */
+
+ _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = ECORE_X_ATOM_WM_TAKE_FOCUS;
+ _ecore_xcb_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] = ECORE_X_ATOM_NET_WM_PING;
+ _ecore_xcb_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+
+ _ecore_xcb_init_count++;
+
+ _ecore_xcb_private_window = ecore_x_window_override_new(0, -77, -777, 123, 456);
+
+ /* We finally get the replies of the QueryVersion request */
+#ifdef ECORE_XCB_DAMAGE
+ _ecore_x_damage_init_finalize();
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_COMPOSITE
+ _ecore_x_composite_init_finalize();
+#endif /* ECORE_XCB_COMPOSITE */
+#ifdef ECORE_XCB_DPMS
+ _ecore_x_dpms_init_finalize();
+#endif /* ECORE_XCB_DPMS */
+#ifdef ECORE_XCB_RANDR
+ _ecore_x_randr_init_finalize();
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_SCREENSAVER
+ _ecore_x_screensaver_init_finalize();
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+ _ecore_x_shape_init_finalize();
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+ _ecore_x_sync_init_finalize();
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_FIXES
+ _ecore_x_xfixes_init_finalize();
+#endif /* ECORE_XCB_FIXES */
+#ifdef ECORE_XCB_XINERAMA
+ _ecore_x_xinerama_init_finalize();
+#endif /* ECORE_XCB_XINERAMA */
+
+ return _ecore_xcb_init_count;
+
+ free_event_handlers:
+ free(_ecore_xcb_event_handlers);
+ _ecore_xcb_event_handlers = NULL;
+ finalize_extensions:
+ /* We get the replies of the QueryVersion request because we leave */
+#ifdef ECORE_XCB_DAMAGE
+ _ecore_x_damage_init_finalize();
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_COMPOSITE
+ _ecore_x_composite_init_finalize();
+#endif /* ECORE_XCB_COMPOSITE */
+#ifdef ECORE_XCB_DPMS
+ _ecore_x_dpms_init_finalize();
+#endif /* ECORE_XCB_DPMS */
+#ifdef ECORE_XCB_RANDR
+ _ecore_x_randr_init_finalize();
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_SCREENSAVER
+ _ecore_x_screensaver_init_finalize();
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+ _ecore_x_shape_init_finalize();
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+ _ecore_x_sync_init_finalize();
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_FIXES
+ _ecore_x_xfixes_init_finalize();
+#endif /* ECORE_XCB_FIXES */
+#ifdef ECORE_XCB_XINERAMA
+ _ecore_x_xinerama_init_finalize();
+#endif /* ECORE_XCB_XINERAMA */
+ ecore_event_shutdown();
+ close_connection:
+ _ecore_x_atom_init_finalize(atom_cookies);
+ xcb_disconnect(_ecore_xcb_conn);
+ _ecore_xcb_fd_handler_handle = NULL;
+ _ecore_xcb_conn = NULL;
+
+ return --_ecore_xcb_init_count;
+}
+
+static int
+_ecore_x_shutdown(int close_display)
+{
+ if (--_ecore_xcb_init_count != 0)
+ return _ecore_xcb_init_count;
+
+ if (!_ecore_xcb_conn) return _ecore_xcb_init_count;
+
+ if (close_display)
+ xcb_disconnect(_ecore_xcb_conn);
+ else
+ close(xcb_get_file_descriptor(_ecore_xcb_conn));
+ ecore_event_shutdown();
+ free(_ecore_xcb_event_handlers);
+ ecore_main_fd_handler_del(_ecore_xcb_fd_handler_handle);
+ ecore_event_filter_del(_ecore_xcb_filter_handler);
+ _ecore_xcb_fd_handler_handle = NULL;
+ _ecore_xcb_filter_handler = NULL;
+ _ecore_xcb_conn = NULL;
+ _ecore_xcb_event_handlers = NULL;
+ _ecore_x_selection_shutdown();
+ _ecore_x_dnd_shutdown();
+ ecore_x_netwm_shutdown();
+ _ecore_x_reply_shutdown();
+
+ return _ecore_xcb_init_count;
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * In shutting down the library, the X display connection is terminated
+ * and any event handlers for it are removed.
+ *
+ * @return The number of times the library has been initialized without
+ * being shut down.
+ * @ingroup Ecore_Xcb_Init_Group
+ */
+EAPI int
+ecore_x_shutdown(void)
+{
+ return _ecore_x_shutdown(1);
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * As ecore_xcb_shutdown, except do not close Display, only connection.
+ *
+ * @ingroup Ecore_Xcb_Init_Group
+ */
+EAPI int
+ecore_x_disconnect(void)
+{
+ return _ecore_x_shutdown(0);
+}
+
+/**
+ * @defgroup Ecore_Xcb_Display_Attr_Group X Display Attributes
+ *
+ * Functions that set and retrieve X display attributes.
+ */
+
+EAPI Ecore_X_Display *
+ecore_x_display_get(void)
+{
+ return NULL;
+}
+
+/**
+ * Retrieves the Ecore_X_Connection handle used for the current X connection.
+ * @return The current X connection.
+ * @ingroup Ecore_Xcb_Display_Attr_Group
+ */
+EAPI Ecore_X_Connection *
+ecore_x_connection_get(void)
+{
+ return (Ecore_X_Connection *)_ecore_xcb_conn;
+}
+
+/**
+ * Retrieves the X display file descriptor.
+ * @return The current X display file descriptor.
+ * @ingroup Ecore_Xcb_Display_Attr_Group
+ */
+EAPI int
+ecore_x_fd_get(void)
+{
+ return xcb_get_file_descriptor(_ecore_xcb_conn);
+}
+
+/**
+ * Retrieves the Ecore_X_Screen handle used for the current X connection.
+ * @return The current default screen.
+ * @ingroup Ecore_Xcb_Display_Attr_Group
+ */
+EAPI Ecore_X_Screen *
+ecore_x_default_screen_get(void)
+{
+ return (Ecore_X_Screen *)_ecore_xcb_screen;
+}
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ * @ingroup Ecore_Xcb_Display_Attr_Group
+ */
+EAPI void
+ecore_x_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_xcb_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_xcb_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ * @ingroup Ecore_Xcb_Display_Attr_Group
+ */
+EAPI double
+ecore_x_double_click_time_get(void)
+{
+ return _ecore_xcb_double_click_time;
+}
+
+/**
+ * @defgroup Ecore_Xcb_Flush_Group X Synchronization Functions
+ *
+ * Functions that ensure that all commands that have been issued by the
+ * Ecore X library have been sent to the server.
+ */
+
+/**
+ * Sends all X commands in the X Display buffer.
+ * @ingroup Ecore_Xcb_Flush_Group
+ */
+EAPI void
+ecore_x_flush(void)
+{
+ xcb_flush(_ecore_xcb_conn);
+}
+
+/**
+ * Flushes the command buffer and waits until all requests have been
+ * processed by the server.
+ * @ingroup Ecore_Xcb_Flush_Group
+ */
+EAPI void
+ecore_x_sync(void)
+{
+ free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL));
+}
+
+/**
+ * Kill all clients with subwindows under a given window.
+ *
+ * You can kill all clients connected to the X server by using
+ * @ref ecore_x_window_root_list to get a list of root windows, and
+ * then passing each root window to this function.
+ *
+ * @param root The window whose children will be killed.
+ */
+EAPI void
+ecore_x_killall(Ecore_X_Window root)
+{
+ int screens;
+ int i;
+
+ xcb_grab_server(_ecore_xcb_conn);
+ screens = xcb_setup_roots_iterator (xcb_get_setup (_ecore_xcb_conn)).rem;
+
+ /* Tranverse window tree starting from root, and drag each
+ * before the firing squad */
+ for (i = 0; i < screens; ++i)
+ {
+ xcb_query_tree_cookie_t cookie;
+ xcb_query_tree_reply_t *reply;
+
+ cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, root);
+ reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply)
+ {
+ xcb_window_iterator_t iter;
+
+ iter = xcb_query_tree_children_iterator(reply);
+ for (; iter.rem; xcb_window_next(&iter))
+ xcb_kill_client(_ecore_xcb_conn, *iter.data);
+ free(reply);
+ }
+ }
+
+ xcb_ungrab_server(_ecore_xcb_conn);
+ free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL));
+}
+
+/**
+ * Kill a specific client
+ *
+ * You can kill a specific client woning window @p window
+ *
+ * @param window Window of the client to be killed
+ */
+EAPI void
+ecore_x_kill(Ecore_X_Window window)
+{
+ xcb_kill_client(_ecore_xcb_conn, window);
+}
+
+/**
+ * Return the last event time
+ */
+EAPI Ecore_X_Time
+ecore_x_current_time_get(void)
+{
+ return _ecore_xcb_event_last_time;
+}
+
+static void
+handle_event(xcb_generic_event_t *ev)
+{
+ uint8_t response_type = ev->response_type & ~0x80;
+
+ if (response_type < _ecore_xcb_event_handlers_num)
+ {
+ if (_ecore_xcb_event_handlers[XCB_EVENT_ANY])
+ _ecore_xcb_event_handlers[XCB_EVENT_ANY] (ev);
+
+ if (_ecore_xcb_event_handlers[response_type])
+ _ecore_xcb_event_handlers[response_type] (ev);
+ }
+}
+
+static int
+_ecore_xcb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ xcb_connection_t *c;
+ xcb_generic_event_t *ev;
+
+ c = (xcb_connection_t *)data;
+
+/* INF ("nbr events: %d", _ecore_xcb_event_handlers_num); */
+
+ /* We check if _ecore_xcb_event_buffered is NULL or not */
+ if (_ecore_xcb_event_buffered)
+ handle_event(_ecore_xcb_event_buffered);
+
+ while ((ev = xcb_poll_for_event(c)))
+ handle_event(ev);
+
+ return 1;
+}
+
+static int
+_ecore_xcb_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ xcb_connection_t *c;
+
+ c = (xcb_connection_t *)data;
+
+ _ecore_xcb_event_buffered = xcb_poll_for_event(c);
+ if (!_ecore_xcb_event_buffered)
+ return 0;
+
+ return 1;
+}
+
+/* FIXME: possible roundtrip */
+/* FIXME: fix xcb_keysyms. It's ugly !! (reply in xcb_key_symbols_get_keysym) */
+static int
+_ecore_xcb_key_mask_get(xcb_keysym_t sym)
+{
+ xcb_keycode_iterator_t iter;
+ xcb_get_modifier_mapping_cookie_t cookie;
+ xcb_get_modifier_mapping_reply_t *reply;
+ xcb_key_symbols_t *symbols;
+ xcb_keysym_t sym2;
+ int i, j;
+ const int masks[8] =
+ {
+ XCB_MOD_MASK_SHIFT,
+ XCB_MOD_MASK_LOCK,
+ XCB_MOD_MASK_CONTROL,
+ XCB_MOD_MASK_1,
+ XCB_MOD_MASK_2,
+ XCB_MOD_MASK_3,
+ XCB_MOD_MASK_4,
+ XCB_MOD_MASK_5
+ };
+
+ cookie = xcb_get_modifier_mapping_unchecked(_ecore_xcb_conn);
+ symbols = xcb_key_symbols_alloc(_ecore_xcb_conn);
+
+ reply = xcb_get_modifier_mapping_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ {
+ xcb_key_symbols_free(symbols);
+
+ return 0;
+ }
+
+ iter = xcb_get_modifier_mapping_keycodes_iterator(reply);
+
+ for (i = 0; iter.rem; xcb_keycode_next(&iter), i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ sym2 = xcb_key_symbols_get_keysym(symbols, *iter.data, j);
+ if (sym2 != 0) break;
+ }
+ if (sym2 == sym)
+ {
+ int mask;
+
+ mask = masks[j];
+ free(reply);
+ xcb_key_symbols_free(symbols);
+ return mask;
+ }
+ }
+
+ free(reply);
+ xcb_key_symbols_free(symbols);
+
+ return 0;
+}
+
+typedef struct _Ecore_X_Filter_Data Ecore_X_Filter_Data;
+
+struct _Ecore_X_Filter_Data
+{
+ int last_event_type;
+};
+
+static void *
+_ecore_xcb_event_filter_start(void *data __UNUSED__)
+{
+ Ecore_X_Filter_Data *filter_data;
+
+ filter_data = calloc(1, sizeof(Ecore_X_Filter_Data));
+ return filter_data;
+}
+
+static int
+_ecore_xcb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__)
+{
+ Ecore_X_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (!filter_data) return 1;
+ if (type == ECORE_EVENT_MOUSE_MOVE)
+ {
+ if ((filter_data->last_event_type) == ECORE_EVENT_MOUSE_MOVE)
+ {
+ filter_data->last_event_type = type;
+ return 0;
+ }
+ }
+ filter_data->last_event_type = type;
+ return 1;
+}
+
+static void
+_ecore_xcb_event_filter_end(void *data __UNUSED__, void *loop_data)
+{
+ Ecore_X_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (filter_data) free(filter_data);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+/* FIXME: these funcs need categorising */
+/*****************************************************************************/
+
+
+
+
+/**
+ * Get a list of all the root windows on the server.
+ *
+ * @note The returned array will need to be freed after use.
+ * @param num_ret Pointer to integer to put number of windows returned in.
+ * @return An array of all the root windows. @c NULL is returned if memory
+ * could not be allocated for the list, or if @p num_ret is @c NULL.
+ */
+EAPI Ecore_X_Window *
+ecore_x_window_root_list(int *num_ret)
+{
+ xcb_screen_iterator_t iter;
+ const xcb_setup_t *setup;
+ uint8_t i;
+ uint8_t num;
+ Ecore_X_Window *roots;
+/* #ifdef ECORE_XCBXPRINT */
+/* int xp_base, xp_err_base; */
+/* #endif /\* ECORE_XCBXPRINT *\/ */
+
+ if (!num_ret) return NULL;
+ *num_ret = 0;
+
+ /* FIXME: todo... */
+/* #ifdef ECORE_XCBXPRINT */
+/* num = ScreenCount(_ecore_xcb_conn); */
+/* if (ecore_xcb_xprint_query()) */
+/* { */
+/* Screen **ps = NULL; */
+/* int psnum = 0; */
+
+/* ps = XpQueryScreens(_ecore_xcb_conn, &psnum); */
+/* if (ps) */
+/* { */
+/* int overlap, j; */
+
+/* overlap = 0; */
+/* for (i = 0; i < num; i++) */
+/* { */
+/* for (j = 0; j < psnum; j++) */
+/* { */
+/* if (ScreenOfDisplay(_ecore_xcb_conn, i) == ps[j]) */
+/* overlap++; */
+/* } */
+/* } */
+/* roots = malloc((num - overlap) * sizeof(Ecore_X_Window)); */
+/* if (roots) */
+/* { */
+/* int k; */
+
+/* k = 0; */
+/* for (i = 0; i < num; i++) */
+/* { */
+/* int is_print; */
+
+/* is_print = 0; */
+/* for (j = 0; j < psnum; j++) */
+/* { */
+/* if (ScreenOfDisplay(_ecore_xcb_conn, i) == ps[j]) */
+/* { */
+/* is_print = 1; */
+/* break; */
+/* } */
+/* } */
+/* if (!is_print) */
+/* { */
+/* roots[k] = RootWindow(_ecore_xcb_conn, i); */
+/* k++; */
+/* } */
+/* } */
+/* *num_ret = k; */
+/* } */
+/* XFree(ps); */
+/* } */
+/* else */
+/* { */
+/* roots = malloc(num * sizeof(Ecore_X_Window)); */
+/* if (!roots) return NULL; */
+/* *num_ret = num; */
+/* for (i = 0; i < num; i++) */
+/* roots[i] = RootWindow(_ecore_xcb_conn, i); */
+/* } */
+/* } */
+/* else */
+/* { */
+/* roots = malloc(num * sizeof(Ecore_X_Window)); */
+/* if (!roots) return NULL; */
+/* *num_ret = num; */
+/* for (i = 0; i < num; i++) */
+/* roots[i] = RootWindow(_ecore_xcb_conn, i); */
+/* } */
+/* #else */
+ setup = xcb_get_setup (_ecore_xcb_conn);
+ iter = xcb_setup_roots_iterator (setup);
+ num = setup->roots_len;
+ roots = malloc(num * sizeof(Ecore_X_Window));
+ if (!roots) return NULL;
+
+ *num_ret = num;
+ for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
+ roots[i] = iter.data->root;
+/* #endif /\* ECORE_XCBXPRINT *\/ */
+
+ return roots;
+}
+
+EAPI Ecore_X_Window
+ecore_x_window_root_first_get(void)
+{
+ Ecore_X_Window *roots = NULL;
+ Ecore_X_Window root;
+ int num;
+
+ roots = ecore_x_window_root_list(&num);
+ if(!(roots)) return 0;
+
+ if (num > 0)
+ root = roots[0];
+ else
+ root = 0;
+
+ free(roots);
+ return root;
+}
+
+/* FIXME: todo */
+
+static void _ecore_x_window_manage_error(void *data);
+
+static int _ecore_xcb_window_manage_failed = 0;
+static void
+_ecore_x_window_manage_error(void *data __UNUSED__)
+{
+/* if ((ecore_xcb_error_request_get() == X_ChangeWindowAttributes) && */
+/* (ecore_xcb_error_code_get() == BadAccess)) */
+/* _ecore_xcb_window_manage_failed = 1; */
+}
+
+/* FIXME: round trip */
+EAPI int
+ecore_x_window_manage(Ecore_X_Window window)
+{
+ xcb_get_window_attributes_cookie_t cookie_attr;
+ xcb_get_input_focus_cookie_t cookie_sync;
+ xcb_get_window_attributes_reply_t *reply_attr;
+ xcb_get_input_focus_reply_t *reply_sync;
+ uint32_t value_list;
+
+ cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
+ cookie_sync = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
+
+ reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL);
+ if (!reply_attr)
+ {
+ reply_sync = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie_sync, NULL);
+ if (reply_sync) free(reply_sync);
+ return 0;
+ }
+
+ reply_sync = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie_sync, NULL);
+ if (reply_sync) free(reply_sync);
+
+ _ecore_xcb_window_manage_failed = 0;
+ /* FIXME: no error code yet */
+ /* ecore_xcb_error_handler_set(_ecore_xcb_window_manage_error, NULL); */
+
+ value_list =
+ XCB_EVENT_MASK_KEY_PRESS |
+ XCB_EVENT_MASK_KEY_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW |
+ XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_STRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_RESIZE_REDIRECT |
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
+ XCB_EVENT_MASK_PROPERTY_CHANGE |
+ reply_attr->your_event_mask;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_EVENT_MASK,
+ &value_list);
+ free(reply_attr);
+
+ cookie_sync = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
+ if (reply_sync) free(reply_sync);
+
+ /* FIXME: no error code yet */
+ /* ecore_xcb_error_handler_set(NULL, NULL); */
+ if (_ecore_xcb_window_manage_failed)
+ {
+ _ecore_xcb_window_manage_failed = 0;
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+
+
+
+
+
+EAPI int
+ecore_x_pointer_control_set(int accel_num,
+ int accel_denom,
+ int threshold)
+{
+ xcb_change_pointer_control(_ecore_xcb_conn,
+ accel_num, accel_denom, threshold,
+ 1, 1);
+ return 1;
+}
+
+EAPI void
+ecore_x_pointer_control_get_prefetch(void)
+{
+ xcb_get_pointer_control_cookie_t cookie;
+
+ cookie = xcb_get_pointer_control_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+EAPI void
+ecore_x_pointer_control_get_fetch(void)
+{
+ xcb_get_pointer_control_cookie_t cookie;
+ xcb_get_pointer_control_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_pointer_control_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+EAPI int
+ecore_x_pointer_control_get(int *accel_num,
+ int *accel_denom,
+ int *threshold)
+{
+ xcb_get_pointer_control_reply_t *reply;
+
+ if (accel_num) *accel_num = 0;
+ if (accel_denom) *accel_denom = 1;
+ if (threshold) *threshold = 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ if (accel_num) *accel_num = reply->acceleration_numerator;
+ if (accel_denom) *accel_denom = reply->acceleration_denominator;
+ if (threshold) *threshold = reply->threshold;
+
+ return 1;
+}
+
+EAPI int
+ecore_x_pointer_mapping_set(unsigned char *map,
+ int nmap)
+{
+ xcb_set_pointer_mapping(_ecore_xcb_conn, nmap, map);
+ return 1;
+}
+
+EAPI void
+ecore_x_pointer_mapping_get_prefetch(void)
+{
+ xcb_get_pointer_mapping_cookie_t cookie;
+
+ cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+EAPI void
+ecore_x_pointer_mapping_get_fetch(void)
+{
+ xcb_get_pointer_mapping_cookie_t cookie;
+ xcb_get_pointer_mapping_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+EAPI int
+ecore_x_pointer_mapping_get(unsigned char *map,
+ int nmap)
+{
+ xcb_get_pointer_mapping_cookie_t cookie;
+ xcb_get_pointer_mapping_reply_t *reply;
+ uint8_t *tmp;
+ int i;
+
+ cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn);
+ reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return 0;
+
+ if (nmap > xcb_get_pointer_mapping_map_length(reply))
+ return 0;
+
+ tmp = xcb_get_pointer_mapping_map(reply);
+
+ for (i = 0; i < nmap; i++)
+ map[i] = tmp[i];
+
+ return 1;
+}
+
+EAPI int
+ecore_x_pointer_grab(Ecore_X_Window window)
+{
+ xcb_grab_pointer_cookie_t cookie;
+ xcb_grab_pointer_reply_t *reply;
+
+ cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, window,
+ XCB_EVENT_MASK_BUTTON_PRESS |
+ XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW |
+ XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_POINTER_MOTION,
+ XCB_GRAB_MODE_ASYNC,
+ XCB_GRAB_MODE_ASYNC,
+ XCB_NONE, XCB_NONE,
+ XCB_CURRENT_TIME);
+ reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ return 0;
+
+ free(reply);
+
+ return 1;
+}
+
+EAPI int
+ecore_x_pointer_confine_grab(Ecore_X_Window window)
+{
+ xcb_grab_pointer_cookie_t cookie;
+ xcb_grab_pointer_reply_t *reply;
+
+ cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, window,
+ XCB_EVENT_MASK_BUTTON_PRESS |
+ XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW |
+ XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_POINTER_MOTION,
+ XCB_GRAB_MODE_ASYNC,
+ XCB_GRAB_MODE_ASYNC,
+ window, XCB_NONE,
+ XCB_CURRENT_TIME);
+ reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ return 0;
+
+ free(reply);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_pointer_ungrab(void)
+{
+ xcb_ungrab_pointer(_ecore_xcb_conn, XCB_CURRENT_TIME);
+}
+
+EAPI int
+ecore_x_pointer_warp(Ecore_X_Window window,
+ int x,
+ int y)
+{
+ xcb_warp_pointer(_ecore_xcb_conn, XCB_NONE, window, 0, 0, 0, 0, x, y);
+
+ return 1;
+}
+
+EAPI int
+ecore_x_keyboard_grab(Ecore_X_Window window)
+{
+ xcb_grab_keyboard_cookie_t cookie;
+ xcb_grab_keyboard_reply_t *reply;
+
+ cookie = xcb_grab_keyboard_unchecked(_ecore_xcb_conn, 0, window,
+ XCB_CURRENT_TIME,
+ XCB_GRAB_MODE_ASYNC,
+ XCB_GRAB_MODE_ASYNC);
+ reply = xcb_grab_keyboard_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ return 0;
+
+ free(reply);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_keyboard_ungrab(void)
+{
+ xcb_ungrab_keyboard(_ecore_xcb_conn, XCB_CURRENT_TIME);
+}
+
+EAPI void
+ecore_x_grab(void)
+{
+ _ecore_xcb_grab_count++;
+
+ if (_ecore_xcb_grab_count == 1)
+ xcb_grab_server(_ecore_xcb_conn);
+}
+
+EAPI void
+ecore_x_ungrab(void)
+{
+ _ecore_xcb_grab_count--;
+ if (_ecore_xcb_grab_count < 0)
+ _ecore_xcb_grab_count = 0;
+
+ if (_ecore_xcb_grab_count == 0)
+ {
+ xcb_ungrab_server(_ecore_xcb_conn);
+ free(xcb_get_input_focus_reply(_ecore_xcb_conn, xcb_get_input_focus(_ecore_xcb_conn), NULL));
+ }
+}
+
+int _ecore_window_grabs_num = 0;
+Ecore_X_Window *_ecore_window_grabs = NULL;
+int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
+void *_ecore_window_grab_replay_data;
+
+EAPI void
+ecore_x_passive_grab_replay_func_set(int (*func) (void *data,
+ int event_type,
+ void *event),
+ void *data)
+{
+ _ecore_window_grab_replay_func = func;
+ _ecore_window_grab_replay_data = data;
+}
+
+EAPI void
+ecore_x_window_button_grab(Ecore_X_Window window,
+ int button,
+ Ecore_X_Event_Mask event_mask,
+ int mod,
+ int any_mod)
+{
+ int i;
+ uint16_t m;
+ uint16_t locks[8];
+ uint16_t ev;
+
+ m = _ecore_xcb_event_modifier(mod);
+ if (any_mod) m = XCB_BUTTON_MASK_ANY;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ ev = event_mask;
+ for (i = 0; i < 8; i++)
+ xcb_grab_button(_ecore_xcb_conn, 0, window, ev,
+ XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
+ XCB_NONE, XCB_NONE, button, m | locks[i]);
+ _ecore_window_grabs_num++;
+ _ecore_window_grabs = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num * sizeof(Ecore_X_Window));
+ _ecore_window_grabs[_ecore_window_grabs_num - 1] = window;
+}
+
+void
+_ecore_x_sync_magic_send(int val,
+ Ecore_X_Window swindow)
+{
+ xcb_client_message_event_t ev;
+
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 32;
+ ev.window = _ecore_xcb_private_window;
+ ev.type = 27777;
+ ev.data.data32[0] = 0x7162534;
+ ev.data.data32[1] = 0x10000000 + val;
+ ev.data.data32[2] = swindow;
+
+ xcb_send_event(_ecore_xcb_conn, 0, _ecore_xcb_private_window,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+}
+
+void
+_ecore_x_window_grab_remove(Ecore_X_Window window)
+{
+ int i, shuffle = 0;
+
+ if (_ecore_window_grabs_num > 0)
+ {
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if (shuffle) _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
+ if ((!shuffle) && (_ecore_window_grabs[i] == window))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_window_grabs_num--;
+ _ecore_window_grabs = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num * sizeof(Ecore_X_Window));
+ }
+ }
+}
+
+EAPI void
+ecore_x_window_button_ungrab(Ecore_X_Window window,
+ int button,
+ int mod,
+ int any_mod)
+{
+ int i;
+ uint16_t m;
+ uint16_t locks[8];
+
+ m = _ecore_xcb_event_modifier(mod);
+ if (any_mod) m = XCB_BUTTON_MASK_ANY;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ xcb_ungrab_button(_ecore_xcb_conn, button, window, m | locks[i]);
+ _ecore_x_sync_magic_send(1, window);
+}
+
+int _ecore_key_grabs_num = 0;
+Ecore_X_Window *_ecore_key_grabs = NULL;
+
+EAPI void
+ecore_x_window_key_grab(Ecore_X_Window window,
+ const char *key,
+ int mod,
+ int any_mod)
+{
+ xcb_keycode_t keycode = 0;
+ uint16_t m;
+ uint16_t locks[8];
+ int i;
+
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ /* FIXME: TODO... */
+
+/* else */
+/* { */
+/* KeySym keysym; */
+
+/* keysym = XStringToKeysym(key); */
+/* if (keysym == NoSymbol) return; */
+/* keycode = XKeysymToKeycode(_ecore_xcb_conn, XStringToKeysym(key)); */
+/* } */
+ if (keycode == 0) return;
+
+ m = _ecore_xcb_event_modifier(mod);
+ if (any_mod) m = XCB_BUTTON_MASK_ANY;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ xcb_grab_key(_ecore_xcb_conn, 1, window, m | locks[i], keycode,
+ XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
+ _ecore_key_grabs_num++;
+ _ecore_key_grabs = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Ecore_X_Window));
+ _ecore_key_grabs[_ecore_key_grabs_num - 1] = window;
+}
+
+void
+_ecore_x_key_grab_remove(Ecore_X_Window window)
+{
+ int i, shuffle = 0;
+
+ if (_ecore_key_grabs_num > 0)
+ {
+ for (i = 0; i < _ecore_key_grabs_num; i++)
+ {
+ if (shuffle) _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
+ if ((!shuffle) && (_ecore_key_grabs[i] == window))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_key_grabs_num--;
+ _ecore_key_grabs = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Ecore_X_Window));
+ }
+ }
+}
+
+EAPI void
+ecore_x_window_key_ungrab(Ecore_X_Window window,
+ const char *key,
+ int mod,
+ int any_mod)
+{
+ xcb_keycode_t keycode = 0;
+ uint16_t m;
+ uint16_t locks[8];
+ int i;
+
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ /* FIXME: todo... */
+
+/* else */
+/* { */
+/* KeySym keysym; */
+
+/* keysym = XStringToKeysym(key); */
+/* if (keysym == NoSymbol) return; */
+/* keycode = XKeysymToKeycode(_ecore_xcb_conn, XStringToKeysym(key)); */
+/* } */
+ if (keycode == 0) return;
+
+ m = _ecore_xcb_event_modifier(mod);
+ if (any_mod) m = XCB_BUTTON_MASK_ANY;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ xcb_ungrab_key(_ecore_xcb_conn, keycode, window, m | locks[i]);
+ _ecore_x_sync_magic_send(2, window);
+}
+
+/**
+ * Send client message with given type and format 32.
+ *
+ * @param window The window the message is sent to.
+ * @param type The client message type.
+ * @param mask The client message mask.
+ * @param d0 The client message data item 1
+ * @param d1 The client message data item 2
+ * @param d2 The client message data item 3
+ * @param d3 The client message data item 4
+ * @param d4 The client message data item 5
+ *
+ * @return !0 on success.
+ */
+EAPI int
+ecore_x_client_message32_send(Ecore_X_Window window,
+ Ecore_X_Atom type,
+ Ecore_X_Event_Mask mask,
+ long d0,
+ long d1,
+ long d2,
+ long d3,
+ long d4)
+{
+ xcb_client_message_event_t ev;
+
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 32;
+ ev.window = window;
+ ev.type = type;
+ ev.data.data32[0] = d0;
+ ev.data.data32[1] = d1;
+ ev.data.data32[2] = d2;
+ ev.data.data32[3] = d3;
+ ev.data.data32[4] = d4;
+
+ xcb_send_event(_ecore_xcb_conn, 0, window, mask, (const char *)&ev);
+
+ return 1;
+}
+
+/**
+ * Send client message with given type and format 8.
+ *
+ * @param window The window the message is sent to.
+ * @param type The client message type.
+ * @param data Data to be sent.
+ * @param len Number of data bytes, max 20.
+ *
+ * @return !0 on success.
+ */
+EAPI int
+ecore_x_client_message8_send(Ecore_X_Window window,
+ Ecore_X_Atom type,
+ const void *data,
+ int len)
+{
+ xcb_client_message_event_t ev;
+
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 8;
+ ev.window = window;
+ ev.type = type;
+ if (len > 20)
+ len = 20;
+ memcpy(ev.data.data8, data, len);
+ memset(ev.data.data8 + len, 0, 20 - len);
+
+ xcb_send_event(_ecore_xcb_conn, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+
+ return 1;
+}
+
+/* FIXME: round trip */
+EAPI int
+ecore_x_mouse_move_send(Ecore_X_Window window,
+ int x,
+ int y)
+{
+ xcb_motion_notify_event_t ev;
+ xcb_get_geometry_cookie_t cookie_geom;
+ xcb_translate_coordinates_cookie_t cookie_trans;
+ xcb_get_geometry_reply_t *reply_geom;
+ xcb_translate_coordinates_reply_t *reply_trans;
+
+ cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
+ reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
+ if (!reply_geom) return 0;
+
+ cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y);
+ reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL);
+ if (!reply_trans)
+ {
+ free(reply_geom);
+ return 0;
+ }
+
+ ev.response_type = XCB_MOTION_NOTIFY;
+ ev.detail = 0;
+ ev.time = _ecore_xcb_event_last_time;
+ ev.root = reply_geom->root;
+ ev.event = window;
+ ev.child = window;
+ ev.root_x = reply_trans->dst_x;
+ ev.root_y = reply_trans->dst_y;
+ ev.event_x = x;
+ ev.event_y = y;
+ ev.state = 0;
+ ev.same_screen = 1;
+
+ xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_POINTER_MOTION, (const char *)&ev);
+
+ free(reply_geom);
+ free(reply_trans);
+
+ return 1;
+}
+
+/* FIXME: round trip */
+EAPI int
+ecore_x_mouse_down_send(Ecore_X_Window window,
+ int x,
+ int y,
+ int button)
+{
+ xcb_button_press_event_t ev;
+ xcb_get_geometry_cookie_t cookie_geom;
+ xcb_translate_coordinates_cookie_t cookie_trans;
+ xcb_get_geometry_reply_t *reply_geom;
+ xcb_translate_coordinates_reply_t *reply_trans;
+
+ cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
+ reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
+ if (!reply_geom) return 0;
+
+ cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y);
+ reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL);
+ if (!reply_trans)
+ {
+ free(reply_geom);
+ return 0;
+ }
+
+ ev.response_type = XCB_BUTTON_PRESS;
+ ev.detail = button;
+ ev.time = _ecore_xcb_event_last_time;
+ ev.root = reply_geom->root;
+ ev.event = window;
+ ev.child = window;
+ ev.root_x = reply_trans->dst_x;
+ ev.root_y = reply_trans->dst_y;
+ ev.event_x = x;
+ ev.event_y = y;
+ ev.state = 1 << button;
+ ev.same_screen = 1;
+
+ xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_BUTTON_PRESS, (const char *)&ev);
+
+ free(reply_geom);
+ free(reply_trans);
+
+ return 1;
+}
+
+/* FIXME: round trip */
+EAPI int
+ecore_x_mouse_up_send(Ecore_X_Window window,
+ int x,
+ int y,
+ int button)
+{
+ xcb_button_release_event_t ev;
+ xcb_get_geometry_cookie_t cookie_geom;
+ xcb_translate_coordinates_cookie_t cookie_trans;
+ xcb_get_geometry_reply_t *reply_geom;
+ xcb_translate_coordinates_reply_t *reply_trans;
+
+ cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
+ reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
+ if (!reply_geom) return 0;
+
+ cookie_trans = xcb_translate_coordinates_unchecked(_ecore_xcb_conn, window, reply_geom->root, x, y);
+ reply_trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie_trans, NULL);
+ if (!reply_trans)
+ {
+ free(reply_geom);
+ return 0;
+ }
+
+ ev.response_type = XCB_BUTTON_RELEASE;
+ ev.detail = button;
+ ev.time = _ecore_xcb_event_last_time;
+ ev.root = reply_geom->root;
+ ev.event = window;
+ ev.child = window;
+ ev.root_x = reply_trans->dst_x;
+ ev.root_y = reply_trans->dst_y;
+ ev.event_x = x;
+ ev.event_y = y;
+ ev.state = 0;
+ ev.same_screen = 1;
+
+ xcb_send_event(_ecore_xcb_conn, 1, window, XCB_EVENT_MASK_BUTTON_RELEASE, (const char *)&ev);
+
+ free(reply_geom);
+ free(reply_trans);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_focus_reset(void)
+{
+ xcb_set_input_focus(_ecore_xcb_conn,
+ (uint8_t)XCB_INPUT_FOCUS_POINTER_ROOT,
+ XCB_INPUT_FOCUS_POINTER_ROOT,
+ XCB_CURRENT_TIME);
+}
+
+EAPI void
+ecore_x_events_allow_all(void)
+{
+ xcb_allow_events(_ecore_xcb_conn, XCB_ALLOW_ASYNC_BOTH, XCB_CURRENT_TIME);
+}
+
+EAPI void
+ecore_x_pointer_last_xy_get(int *x,
+ int *y)
+{
+ if (x) *x = _ecore_xcb_event_last_root_x;
+ if (y) *y = _ecore_xcb_event_last_root_y;
+}
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+static int
+_ecore_xcb_event_modifier(unsigned int state)
+{
+ int xmodifiers = 0;
+
+ if (state & ECORE_EVENT_MODIFIER_SHIFT) xmodifiers |= ECORE_X_MODIFIER_SHIFT;
+ if (state & ECORE_EVENT_MODIFIER_CTRL) xmodifiers |= ECORE_X_MODIFIER_CTRL;
+ if (state & ECORE_EVENT_MODIFIER_ALT) xmodifiers |= ECORE_X_MODIFIER_ALT;
+ if (state & ECORE_EVENT_MODIFIER_WIN) xmodifiers |= ECORE_X_MODIFIER_WIN;
+ if (state & ECORE_EVENT_LOCK_SCROLL) xmodifiers |= ECORE_X_LOCK_SCROLL;
+ if (state & ECORE_EVENT_LOCK_NUM) xmodifiers |= ECORE_X_LOCK_NUM;
+ if (state & ECORE_EVENT_LOCK_CAPS) xmodifiers |= ECORE_X_LOCK_CAPS;
+
+ return xmodifiers;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include <string.h>
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Atom_Group XCB Atom Functions
+ *
+ * Functions that operate on atoms.
+ */
+
+/*********/
+/* Atoms */
+/*********/
+
+#include "ecore_x_atoms_decl.h"
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_atom_init and
+ _ecore_xcb_atom_init_finalize. The first one gets the cookies and
+ the second one gets the replies and set the atoms. */
+
+#define FETCH_ATOM(s) \
+ atom_cookies[i] = xcb_intern_atom(_ecore_xcb_conn, 0, strlen(s), s); \
+ i++
+
+#define FETCH_ATOM_FINALIZE(x) \
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, atom_cookies[i], NULL); \
+ x = reply->atom; \
+ free(reply); \
+ i++;
+
+void
+_ecore_x_atom_init(xcb_intern_atom_cookie_t *atom_cookies)
+{
+ int i = 0;
+
+ /* generic atoms */
+ FETCH_ATOM("COMPOUND_TEXT");
+ FETCH_ATOM("FILE_NAME");
+ FETCH_ATOM("TEXT");
+ FETCH_ATOM("UTF8_STRING");
+
+ /* dnd atoms */
+ FETCH_ATOM("JXSelectionWindowProperty");
+ FETCH_ATOM("XdndSelection");
+ FETCH_ATOM("XdndAware");
+ FETCH_ATOM("XdndEnter");
+ FETCH_ATOM("XdndTypeList");
+ FETCH_ATOM("XdndPosition");
+ FETCH_ATOM("XdndActionCopy");
+ FETCH_ATOM("XdndActionMove");
+ FETCH_ATOM("XdndActionPrivate");
+ FETCH_ATOM("XdndActionAsk");
+ FETCH_ATOM("XdndActionList");
+ FETCH_ATOM("XdndActionLink");
+ FETCH_ATOM("XdndActionDescription");
+ FETCH_ATOM("XdndProxy");
+ FETCH_ATOM("XdndStatus");
+ FETCH_ATOM("XdndLeave");
+ FETCH_ATOM("XdndDrop");
+ FETCH_ATOM("XdndFinished");
+
+ /* old E atom */
+ FETCH_ATOM("_E_FRAME_SIZE");
+
+ /* old Gnome atom */
+ FETCH_ATOM("_WIN_LAYER");
+
+ /* ICCCM */
+ FETCH_ATOM("WM_PROTOCOLS");
+ FETCH_ATOM("WM_COLORMAP_WINDOWS");
+
+ FETCH_ATOM("WM_STATE");
+
+ FETCH_ATOM("WM_CHANGE_STATE");
+
+ FETCH_ATOM("WM_TAKE_FOCUS");
+ FETCH_ATOM("WM_SAVE_YOURSELF");
+ FETCH_ATOM("WM_DELETE_WINDOW");
+
+ FETCH_ATOM("WM_COLORMAP_NOTIFY");
+
+ FETCH_ATOM("SM_CLIENT_ID");
+ FETCH_ATOM("WM_CLIENT_LEADER");
+ FETCH_ATOM("WM_WINDOW_ROLE");
+
+ /* Motif WM atom */
+ FETCH_ATOM("_MOTIF_WM_HINTS");
+
+ /* NetWM atoms */
+ FETCH_ATOM("_NET_SUPPORTED");
+ FETCH_ATOM("_NET_CLIENT_LIST");
+ FETCH_ATOM("_NET_CLIENT_LIST_STACKING");
+ FETCH_ATOM("_NET_NUMBER_OF_DESKTOPS");
+ FETCH_ATOM("_NET_DESKTOP_GEOMETRY");
+ FETCH_ATOM("_NET_DESKTOP_VIEWPORT");
+ FETCH_ATOM("_NET_CURRENT_DESKTOP");
+ FETCH_ATOM("_NET_DESKTOP_NAMES");
+ FETCH_ATOM("_NET_ACTIVE_WINDOW");
+ FETCH_ATOM("_NET_WORKAREA");
+ FETCH_ATOM("_NET_SUPPORTING_WM_CHECK");
+ FETCH_ATOM("_NET_VIRTUAL_ROOTS");
+ FETCH_ATOM("_NET_DESKTOP_LAYOUT");
+ FETCH_ATOM("_NET_SHOWING_DESKTOP");
+
+ FETCH_ATOM("_NET_CLOSE_WINDOW");
+ FETCH_ATOM("_NET_MOVERESIZE_WINDOW");
+ FETCH_ATOM("_NET_WM_MOVERESIZE");
+ FETCH_ATOM("_NET_RESTACK_WINDOW");
+ FETCH_ATOM("_NET_REQUEST_FRAME_EXTENTS");
+
+ FETCH_ATOM("_NET_WM_NAME");
+ FETCH_ATOM("_NET_WM_VISIBLE_NAME");
+ FETCH_ATOM("_NET_WM_ICON_NAME");
+ FETCH_ATOM("_NET_WM_VISIBLE_ICON_NAME");
+ FETCH_ATOM("_NET_WM_DESKTOP");
+
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_DESKTOP");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_DOCK");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_TOOLBAR");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_MENU");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_UTILITY");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
+ FETCH_ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
+
+ FETCH_ATOM("_NET_WM_STATE");
+ FETCH_ATOM("_NET_WM_STATE_MODAL");
+ FETCH_ATOM("_NET_WM_STATE_STICKY");
+ FETCH_ATOM("_NET_WM_STATE_MAXIMIZED_VERT");
+ FETCH_ATOM("_NET_WM_STATE_MAXIMIZED_HORZ");
+ FETCH_ATOM("_NET_WM_STATE_SHADED");
+ FETCH_ATOM("_NET_WM_STATE_SKIP_TASKBAR");
+ FETCH_ATOM("_NET_WM_STATE_SKIP_PAGER");
+ FETCH_ATOM("_NET_WM_STATE_HIDDEN");
+ FETCH_ATOM("_NET_WM_STATE_FULLSCREEN");
+ FETCH_ATOM("_NET_WM_STATE_ABOVE");
+ FETCH_ATOM("_NET_WM_STATE_BELOW");
+ FETCH_ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
+
+ FETCH_ATOM("_NET_WM_ALLOWED_ACTIONS");
+ FETCH_ATOM("_NET_WM_ACTION_MOVE");
+ FETCH_ATOM("_NET_WM_ACTION_RESIZE");
+ FETCH_ATOM("_NET_WM_ACTION_MINIMIZE");
+ FETCH_ATOM("_NET_WM_ACTION_SHADE");
+ FETCH_ATOM("_NET_WM_ACTION_STICK");
+ FETCH_ATOM("_NET_WM_ACTION_MAXIMIZE_HORZ");
+ FETCH_ATOM("_NET_WM_ACTION_MAXIMIZE_VERT");
+ FETCH_ATOM("_NET_WM_ACTION_FULLSCREEN");
+ FETCH_ATOM("_NET_WM_ACTION_CHANGE_DESKTOP");
+ FETCH_ATOM("_NET_WM_ACTION_CLOSE");
+ FETCH_ATOM("_NET_WM_ACTION_ABOVE");
+ FETCH_ATOM("_NET_WM_ACTION_BELOW");
+
+ FETCH_ATOM("_NET_WM_STRUT");
+ FETCH_ATOM("_NET_WM_STRUT_PARTIAL");
+ FETCH_ATOM("_NET_WM_ICON_GEOMETRY");
+ FETCH_ATOM("_NET_WM_ICON");
+ FETCH_ATOM("_NET_WM_PID");
+ FETCH_ATOM("_NET_WM_HANDLED_ICONS");
+ FETCH_ATOM("_NET_WM_USER_TIME");
+ FETCH_ATOM("_NET_STARTUP_ID");
+ FETCH_ATOM("_NET_FRAME_EXTENTS");
+
+ FETCH_ATOM("_NET_WM_PING");
+ FETCH_ATOM("_NET_WM_SYNC_REQUEST");
+ FETCH_ATOM("_NET_WM_SYNC_REQUEST_COUNTER");
+
+ FETCH_ATOM("_NET_WM_WINDOW_OPACITY");
+ FETCH_ATOM("_NET_WM_WINDOW_SHADOW");
+ FETCH_ATOM("_NET_WM_WINDOW_SHADE");
+
+ FETCH_ATOM("_NET_STARTUP_INFO_BEGIN");
+ FETCH_ATOM("_NET_STARTUP_INFO");
+
+ /* selection atoms */
+ FETCH_ATOM("TARGETS");
+ FETCH_ATOM("CLIPBOARD");
+ FETCH_ATOM("_ECORE_SELECTION_PRIMARY");
+ FETCH_ATOM("_ECORE_SELECTION_SECONDARY");
+ FETCH_ATOM("_ECORE_SELECTION_CLIPBOARD");
+
+ /* These atoms are already internally defined */
+ ECORE_X_ATOM_SELECTION_PRIMARY = 1;
+ ECORE_X_ATOM_SELECTION_SECONDARY = 2;
+ ECORE_X_ATOM_ATOM = 4;
+ ECORE_X_ATOM_CARDINAL = 6;
+ ECORE_X_ATOM_STRING = 31;
+ ECORE_X_ATOM_WINDOW = 33;
+ ECORE_X_ATOM_WM_NAME = 39;
+ ECORE_X_ATOM_WM_ICON_NAME = 37;
+ ECORE_X_ATOM_WM_NORMAL_HINTS = 40;
+ ECORE_X_ATOM_WM_SIZE_HINTS = 41;
+ ECORE_X_ATOM_WM_HINTS = 35;
+ ECORE_X_ATOM_WM_CLASS = 67;
+ ECORE_X_ATOM_WM_TRANSIENT_FOR = 68;
+ ECORE_X_ATOM_WM_COMMAND = 34;
+ ECORE_X_ATOM_WM_CLIENT_MACHINE = 36;
+ ECORE_X_ATOM_WM_ICON_SIZE = 38;
+
+ /* Initialize the globally defined xdnd atoms */
+ ECORE_X_DND_ACTION_COPY = ECORE_X_ATOM_XDND_ACTION_COPY;
+ ECORE_X_DND_ACTION_MOVE = ECORE_X_ATOM_XDND_ACTION_MOVE;
+ ECORE_X_DND_ACTION_LINK = ECORE_X_ATOM_XDND_ACTION_LINK;
+ ECORE_X_DND_ACTION_ASK = ECORE_X_ATOM_XDND_ACTION_ASK;
+ ECORE_X_DND_ACTION_PRIVATE = ECORE_X_ATOM_XDND_ACTION_PRIVATE;
+}
+
+void
+_ecore_x_atom_init_finalize(xcb_intern_atom_cookie_t *atom_cookies)
+{
+ xcb_intern_atom_reply_t *reply = NULL;
+ int i = 0;
+
+ /* generic atoms */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_COMPOUND_TEXT);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_FILE_NAME);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_TEXT);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_UTF8_STRING);
+
+ /* dnd atoms */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SELECTION_PROP_XDND);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SELECTION_XDND);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_AWARE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ENTER);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_TYPE_LIST);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_POSITION);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ACTION_COPY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ACTION_MOVE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ACTION_PRIVATE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ACTION_ASK);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ACTION_LIST);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ACTION_LINK);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_ACTION_DESCRIPTION);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_PROXY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_STATUS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_LEAVE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_DROP);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_XDND_FINISHED);
+
+ /* old E atom */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_E_FRAME_SIZE);
+
+ /* old Gnome atom */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WIN_LAYER);
+
+ /* ICCCM */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_PROTOCOLS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_STATE);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_CHANGE_STATE);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_TAKE_FOCUS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_SAVE_YOURSELF);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_DELETE_WINDOW);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_COLORMAP_NOTIFY);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SM_CLIENT_ID);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_CLIENT_LEADER);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_WM_WINDOW_ROLE);
+
+ /* Motif WM atom */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_MOTIF_WM_HINTS);
+
+ /* NetWM atoms */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_SUPPORTED);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_CLIENT_LIST);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_CLIENT_LIST_STACKING);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_DESKTOP_GEOMETRY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_DESKTOP_VIEWPORT);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_CURRENT_DESKTOP);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_DESKTOP_NAMES);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_ACTIVE_WINDOW);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WORKAREA);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_VIRTUAL_ROOTS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_DESKTOP_LAYOUT);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_SHOWING_DESKTOP);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_CLOSE_WINDOW);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_MOVERESIZE_WINDOW);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_MOVERESIZE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_RESTACK_WINDOW);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_NAME);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ICON_NAME);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_DESKTOP);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_MODAL);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_STICKY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_SHADED);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_HIDDEN);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_ABOVE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_BELOW);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_MOVE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_RESIZE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_SHADE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_STICK);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_CLOSE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_ABOVE);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ACTION_BELOW);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STRUT);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_STRUT_PARTIAL);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ICON_GEOMETRY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_ICON);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_PID);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_HANDLED_ICONS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_USER_TIME);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_STARTUP_ID);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_FRAME_EXTENTS);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_PING);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_SYNC_REQUEST);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_OPACITY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_SHADOW);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_WM_WINDOW_SHADE);
+
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_NET_STARTUP_INFO);
+
+ /* selection atoms */
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SELECTION_TARGETS);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SELECTION_CLIPBOARD);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SELECTION_PROP_PRIMARY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SELECTION_PROP_SECONDARY);
+ FETCH_ATOM_FINALIZE(ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD);
+}
+
+
+/**
+ * Sends the InternAtom request.
+ * @param name Name of the requested atom.
+ * @ingroup Ecore_X_Atom_Group
+ */
+EAPI void
+ecore_x_atom_get_prefetch(const char *name)
+{
+ xcb_intern_atom_cookie_t cookie;
+
+ cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(name), name);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the InternAtom request sent by ecore_x_atom_get_prefetch().
+ * @ingroup Ecore_X_Atom_Group
+ */
+EAPI void
+ecore_x_atom_get_fetch(void)
+{
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Retrieves the atom value associated to a name.
+ * @param name Unused.
+ * @return Associated atom value.
+ *
+ * Retrieves the atom value associated to a name. The reply is the
+ * returned value of the function ecore_xcb_intern_atom_reply(). If
+ * @p reply is @c NULL, the NULL atom is returned. Otherwise, the atom
+ * associated to the name is returned.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_atom_get_prefetch(), which sends the InternAtom request,
+ * then ecore_x_atom_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Atom_Group
+ */
+EAPI Ecore_X_Atom
+ecore_x_atom_get(const char *name __UNUSED__)
+{
+ xcb_intern_atom_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return XCB_NONE;
+
+ return reply->atom;
+}
+
+
+/**
+ * Sends the GetAtomName request.
+ * @param atom Atom to get the name from.
+ * @ingroup Ecore_X_Atom_Group
+ */
+EAPI void
+ecore_x_get_atom_name_prefetch(Ecore_X_Atom atom)
+{
+ xcb_get_atom_name_cookie_t cookie;
+
+ cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, atom);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetAtomName request sent by ecore_x_get_atom_name_prefetch().
+ * @ingroup Ecore_X_Atom_Group
+ */
+EAPI void
+ecore_x_get_atom_name_fetch(void)
+{
+ xcb_get_atom_name_cookie_t cookie;
+ xcb_get_atom_name_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Retrieves the name of the given atom.
+ * @param atom Unused.
+ * @return The name of the atom.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_atom_name_prefetch(), which sends the GetAtomName request,
+ * then ecore_x_get_atom_name_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Atom_Group
+ */
+EAPI char *
+ecore_x_atom_name_get(Ecore_X_Atom atom)
+{
+ xcb_get_atom_name_reply_t *reply;
+ char *name;
+ int length;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return NULL;
+
+ length = xcb_get_atom_name_name_length(reply);
+ name = (char *)malloc(sizeof(char) * (length + 1));
+ if (!name) return NULL;
+
+ memcpy(name, xcb_get_atom_name_name(reply), length);
+ name[length] = '\0';
+
+ return name;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+/**
+ * @defgroup Ecore_X_Composite_Group X Composite Extension Functions
+ *
+ * Functions related to the X Composite extension.
+ */
+
+#ifdef ECORE_XCB_COMPOSITE
+static uint8_t _composite_available = 0;
+static xcb_composite_query_version_cookie_t _ecore_xcb_composite_init_cookie;
+#endif /* ECORE_XCB_COMPOSITE */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_composite_init and
+ _ecore_xcb_composite_init_finalize. The first one gets the cookies and
+ the second one gets the replies. */
+
+void
+_ecore_x_composite_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_COMPOSITE
+ if (reply && reply->present)
+ _ecore_xcb_composite_init_cookie = xcb_composite_query_version_unchecked(_ecore_xcb_conn, XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION);
+#endif /* ECORE_XCB_COMPOSITE */
+}
+
+void
+_ecore_x_composite_init_finalize(void)
+{
+#ifdef ECORE_XCB_COMPOSITE
+ xcb_composite_query_version_reply_t *reply;
+
+ reply = xcb_composite_query_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_composite_init_cookie,
+ NULL);
+ if (reply)
+ {
+ if ((reply->major_version == XCB_COMPOSITE_MAJOR_VERSION) &&
+ (reply->minor_version >= XCB_COMPOSITE_MINOR_VERSION))
+ _composite_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_COMPOSITE */
+}
+
+/**
+ * Return whether the Composite Extension is available.
+ * @return 1 if the Composite Extension is available, 0 if not.
+ *
+ * Return 1 if the X server supports the Composite Extension version 0.4
+ * or greater, 0 otherwise.
+ * @ingroup Ecore_X_Composite_Group
+ */
+EAPI int
+ecore_x_composite_query(void)
+{
+#ifdef ECORE_XCB_COMPOSITE
+ return _composite_available;
+#else
+ return 0;
+#endif /* ECORE_XCB_COMPOSITE */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+#include <xcb/shm.h>
+#include <xcb/xcb_image.h>
+
+
+extern int _ecore_xcb_xcursor;
+
+
+EAPI int
+ecore_x_cursor_color_supported_get(void)
+{
+ return _ecore_xcb_xcursor;
+}
+
+EAPI Ecore_X_Cursor
+ecore_x_cursor_new(Ecore_X_Window window,
+ int *pixels,
+ int w,
+ int h,
+ int hot_x,
+ int hot_y)
+{
+ Ecore_X_Cursor cursor = 0;
+
+#ifdef ECORE_XCB_CURSOR
+ if (_ecore_x_xcursor)
+ {
+ Cursor c;
+ XcursorImage *xci;
+
+ xci = XcursorImageCreate(w, h);
+ if (xci)
+ {
+ int i;
+
+ xci->xhot = hot_x;
+ xci->yhot = hot_y;
+ xci->delay = 0;
+ for (i = 0; i < (w * h); i++)
+ {
+// int r, g, b, a;
+//
+// a = (pixels[i] >> 24) & 0xff;
+// r = (((pixels[i] >> 16) & 0xff) * a) / 0xff;
+// g = (((pixels[i] >> 8 ) & 0xff) * a) / 0xff;
+// b = (((pixels[i] ) & 0xff) * a) / 0xff;
+ xci->pixels[i] = pixels[i];
+// (a << 24) | (r << 16) | (g << 8) | (b);
+ }
+ c = XcursorImageLoadCursor(_ecore_x_disp, xci);
+ XcursorImageDestroy(xci);
+ return c;
+ }
+ }
+ else
+#endif /* ECORE_XCB_CURSOR */
+ {
+ const uint32_t dither[2][2] =
+ {
+ {0, 2},
+ {3, 1}
+ };
+ Ecore_X_Drawable draw;
+ Ecore_X_Pixmap pixmap;
+ Ecore_X_Pixmap mask;
+ Ecore_X_GC gc;
+ xcb_image_t *image;
+ uint32_t *pix;
+ uint8_t fr;
+ uint8_t fg;
+ uint8_t fb;
+ uint8_t br;
+ uint8_t bg;
+ uint8_t bb;
+ uint32_t brightest = 0;
+ uint32_t darkest = 255 * 3;
+ uint16_t x;
+ uint16_t y;
+
+ draw = window;
+ pixmap = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn,
+ 1, pixmap, draw,
+ 1, 1);
+ mask = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn,
+ 1, mask, draw,
+ 1, 1);
+
+ image = xcb_image_create_native(_ecore_xcb_conn, w, h,
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ 32, NULL, ~0, NULL);
+ image->data = malloc(image->size);
+
+ fr = 0x00; fg = 0x00; fb = 0x00;
+ br = 0xff; bg = 0xff; bb = 0xff;
+ pix = (uint32_t *)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ uint8_t r, g, b, a;
+
+ a = (pix[0] >> 24) & 0xff;
+ r = (pix[0] >> 16) & 0xff;
+ g = (pix[0] >> 8 ) & 0xff;
+ b = (pix[0] ) & 0xff;
+ if (a > 0)
+ {
+ if ((uint32_t)(r + g + b) > brightest)
+ {
+ brightest = r + g + b;
+ br = r;
+ bg = g;
+ bb = b;
+ }
+ if ((uint32_t)(r + g + b) < darkest)
+ {
+ darkest = r + g + b;
+ fr = r;
+ fg = g;
+ fb = b;
+ }
+ }
+ pix++;
+ }
+ }
+
+ pix = (uint32_t *)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ uint32_t v;
+ uint8_t r, g, b;
+ int32_t d1, d2;
+
+ r = (pix[0] >> 16) & 0xff;
+ g = (pix[0] >> 8 ) & 0xff;
+ b = (pix[0] ) & 0xff;
+ d1 =
+ ((r - fr) * (r - fr)) +
+ ((g - fg) * (g - fg)) +
+ ((b - fb) * (b - fb));
+ d2 =
+ ((r - br) * (r - br)) +
+ ((g - bg) * (g - bg)) +
+ ((b - bb) * (b - bb));
+ if (d1 + d2)
+ {
+ v = (((d2 * 255) / (d1 + d2)) * 5) / 256;
+ if (v > dither[x & 0x1][y & 0x1]) v = 1;
+ else v = 0;
+ }
+ else
+ {
+ v = 0;
+ }
+ xcb_image_put_pixel(image, x, y, v);
+ pix++;
+ }
+ }
+ draw = pixmap;
+ gc = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_gc(_ecore_xcb_conn, gc, draw, 0, NULL);
+ xcb_image_put(_ecore_xcb_conn, draw, gc, image, 0, 0, 0);
+ xcb_free_gc(_ecore_xcb_conn, gc);
+
+ pix = (uint32_t *)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ uint32_t v;
+
+ v = (((pix[0] >> 24) & 0xff) * 5) / 256;
+ if (v > dither[x & 0x1][y & 0x1]) v = 1;
+ else v = 0;
+ xcb_image_put_pixel(image, x, y, v);
+ pix++;
+ }
+ }
+ draw = mask;
+ gc = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_gc (_ecore_xcb_conn, gc, draw, 0, NULL);
+ xcb_image_put(_ecore_xcb_conn, draw, gc, image, 0, 0, 0);
+ xcb_free_gc(_ecore_xcb_conn, gc);
+
+ free(image->data);
+ image->data = NULL;
+ xcb_image_destroy(image);
+
+ cursor = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_cursor (_ecore_xcb_conn, cursor,
+ pixmap, mask,
+ fr << 8 | fr,
+ fg << 8 | fg,
+ fb << 8 | fb,
+ br << 8 | br,
+ bg << 8 | bg,
+ bb << 8 | bb,
+ hot_x,
+ hot_y);
+ xcb_free_pixmap(_ecore_xcb_conn, pixmap);
+ xcb_free_pixmap(_ecore_xcb_conn, mask);
+
+ return cursor;
+ }
+ return 0;
+}
+
+EAPI void
+ecore_x_cursor_free(Ecore_X_Cursor cursor)
+{
+ xcb_free_cursor(_ecore_xcb_conn, cursor);
+}
+
+/*
+ * Returns the cursor for the given shape.
+ * Note that the return value must not be freed with
+ * ecore_x_cursor_free()!
+ */
+EAPI Ecore_X_Cursor
+ecore_x_cursor_shape_get(int shape)
+{
+ Ecore_X_Cursor cursor;
+ xcb_font_t font;
+
+ /* Shapes are defined in Ecore_X_Cursor.h */
+ font = xcb_generate_id(_ecore_xcb_conn);
+ xcb_open_font(_ecore_xcb_conn, font, strlen("cursor"), "cursor");
+
+ cursor = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_glyph_cursor (_ecore_xcb_conn,
+ cursor,
+ font,
+ font,
+ shape,
+ shape + 1,
+ 0, 0, 0,
+ 65535, 65535, 65535);
+
+ xcb_close_font(_ecore_xcb_conn, font);
+
+ return cursor;
+}
+
+EAPI void
+ecore_x_cursor_size_set(int size)
+{
+#ifdef ECORE_XCB_CURSOR
+ XcursorSetDefaultSize(_ecore_x_disp, size);
+#else
+ size = 0;
+#endif /* ECORE_XCB_CURSOR */
+}
+
+EAPI int
+ecore_x_cursor_size_get(void)
+{
+#ifdef ECORE_XCB_CURSOR
+ return XcursorGetDefaultSize(_ecore_x_disp);
+#else
+ return 0;
+#endif /* ECORE_XCB_CURSOR */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Damage_Group X Damage Extension Functions
+ *
+ * Functions related to the X Damage extension.
+ */
+
+
+#ifdef ECORE_XCB_DAMAGE
+static uint8_t _damage_available = 0;
+static xcb_damage_query_version_cookie_t _ecore_xcb_damage_init_cookie;
+#endif /* ECORE_XCB_DAMAGE */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_damage_init and
+ _ecore_xcb_damage_init_finalize. The first one gets the cookies and
+ the second one gets the replies. */
+
+void
+_ecore_x_damage_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_DAMAGE
+ if (reply && (reply->present))
+ _ecore_xcb_damage_init_cookie = xcb_damage_query_version_unchecked(_ecore_xcb_conn, 1, 1);
+#endif /* ECORE_XCB_DAMAGE */
+}
+
+void
+_ecore_x_damage_init_finalize(void)
+{
+#ifdef ECORE_XCB_DAMAGE
+ xcb_damage_query_version_reply_t *reply;
+
+ reply = xcb_damage_query_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_damage_init_cookie,
+ NULL);
+ if (reply)
+ {
+ if (reply->major_version >= 1)
+ _damage_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_DAMAGE */
+}
+
+
+/**
+ * Return whether the Damage Extension is available.
+ * @return 1 if the Damage Extension is available, 0 if not.
+ *
+ * Return 1 if the X server supports the Damage Extension version 1.0,
+ * 0 otherwise.
+ * @ingroup Ecore_X_Damage_Group
+ */
+EAPI int
+ecore_x_damage_query(void)
+{
+#ifdef ECORE_XCB_DAMAGE
+ return _damage_available;
+#else
+ return 0;
+#endif /* ECORE_XCB_DAMAGE */
+}
+
+
+/**
+ * Creates a damage object.
+ * @param drawable The drawable to monotor.
+ * @param level The level of the damage report.
+ * @return The damage object.
+ *
+ * Creates a damage object to monitor changes to @p drawable, with the
+ * level @p level.
+ * @ingroup Ecore_X_Damage_Group
+ */
+EAPI Ecore_X_Damage
+ecore_x_damage_new(Ecore_X_Drawable drawable,
+ Ecore_X_Damage_Report_Level level)
+{
+ Ecore_X_Damage damage = 0;
+
+#ifdef ECORE_XCB_DAMAGE
+ damage = xcb_generate_id(_ecore_xcb_conn);
+ xcb_damage_create(_ecore_xcb_conn, damage, drawable, level);
+#endif /* ECORE_XCB_DAMAGE */
+
+ return damage;
+}
+
+
+/**
+ * Destroys a damage object.
+ * @param damage The damage object to destroy.
+ *
+ * Destroys the damage object @p damage.
+ * @ingroup Ecore_X_Damage_Group
+ */
+EAPI void
+ecore_x_damage_free(Ecore_X_Damage damage)
+{
+#ifdef ECORE_XCB_DAMAGE
+ xcb_damage_destroy(_ecore_xcb_conn, damage);
+#endif /* ECORE_XCB_DAMAGE */
+}
+
+
+/**
+ * Synchronously modifies the region.
+ * @param damage The damage object to destroy.
+ * @param repair The repair region.
+ * @param parts The parts region.
+ *
+ * Synchronously modifies the regions in the following manner:
+ * If @p repair is @c XCB_NONE:
+ * 1) parts = damage
+ * 2) damage = <empty>
+ * Otherwise:
+ * 1) parts = damage INTERSECT repair
+ * 2) damage = damage - parts
+ * 3) Generate DamageNotify for remaining damage areas
+ * @ingroup Ecore_X_Damage_Group
+ */
+EAPI void
+ecore_x_damage_subtract(Ecore_X_Damage damage,
+ Ecore_X_Region repair,
+ Ecore_X_Region parts)
+{
+#ifdef ECORE_XCB_DAMAGE
+ xcb_damage_subtract(_ecore_xcb_conn, damage, repair, parts);
+#endif /* ECORE_XCB_DAMAGE */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+EAPI int ECORE_X_EVENT_XDND_ENTER = 0;
+EAPI int ECORE_X_EVENT_XDND_POSITION = 0;
+EAPI int ECORE_X_EVENT_XDND_STATUS = 0;
+EAPI int ECORE_X_EVENT_XDND_LEAVE = 0;
+EAPI int ECORE_X_EVENT_XDND_DROP = 0;
+EAPI int ECORE_X_EVENT_XDND_FINISHED = 0;
+
+static Ecore_X_DND_Source *_source = NULL;
+static Ecore_X_DND_Target *_target = NULL;
+static int _ecore_x_dnd_init_count = 0;
+
+
+void
+_ecore_x_dnd_init(void)
+{
+ if (!_ecore_x_dnd_init_count)
+ {
+
+ _source = calloc(1, sizeof(Ecore_X_DND_Source));
+ _source->version = ECORE_X_DND_VERSION;
+ _source->win = XCB_NONE;
+ _source->dest = XCB_NONE;
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ _source->prev.window = 0;
+
+ _target = calloc(1, sizeof(Ecore_X_DND_Target));
+ _target->win = XCB_NONE;
+ _target->source = XCB_NONE;
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+
+ ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_DROP = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new();
+ }
+
+ _ecore_x_dnd_init_count++;
+}
+
+void
+_ecore_x_dnd_shutdown(void)
+{
+ _ecore_x_dnd_init_count--;
+ if (_ecore_x_dnd_init_count > 0)
+ return;
+
+ if (_source)
+ free(_source);
+ _source = NULL;
+
+ if (_target)
+ free(_target);
+ _target = NULL;
+
+ _ecore_x_dnd_init_count = 0;
+}
+
+EAPI void
+ecore_x_dnd_aware_set(Ecore_X_Window window,
+ int on)
+{
+ Ecore_X_Atom prop_data = ECORE_X_DND_VERSION;
+
+ if (on)
+ ecore_x_window_prop_property_set(window, ECORE_X_ATOM_XDND_AWARE,
+ ECORE_X_ATOM_ATOM, 32, &prop_data, 1);
+ else
+ ecore_x_window_prop_property_del(window, ECORE_X_ATOM_XDND_AWARE);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ */
+EAPI void
+ecore_x_dnd_version_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ ECORE_X_ATOM_XDND_AWARE,
+ ECORE_X_ATOM_ATOM,
+ 0, LONG_MAX);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_dnd_version_get_prefetch().
+ */
+EAPI void
+ecore_x_dnd_version_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the DnD version.
+ * @param window Unused.
+ * @return 0 on failure, the version otherwise.
+ *
+ * Get the DnD version. Returns 0 on failure, the version otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dnd_version_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_dnd_version_get_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_dnd_version_get(Ecore_X_Window window)
+{
+ unsigned char *prop_data;
+ int num;
+
+ if (ecore_x_window_prop_property_get(window, ECORE_X_ATOM_XDND_AWARE,
+ ECORE_X_ATOM_ATOM, 32, &prop_data, &num))
+ {
+ int version = (int) *prop_data;
+ free(prop_data);
+ return version;
+ }
+ else
+ return 0;
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ */
+EAPI void
+ecore_x_dnd_type_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM,
+ 0, LONG_MAX);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_dnd_type_get_prefetch().
+ */
+EAPI void
+ecore_x_dnd_type_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/* FIXME: round trip (InternAtomGet request) */
+
+/**
+ * Check if the type is set.
+ * @param window Unused.
+ * @param type The type to check
+ * @return 0 on failure, 1 otherwise.
+ *
+ * Check if the type is set. 0 on failure, 1 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dnd_type_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_dnd_type_get_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_dnd_type_isset(Ecore_X_Window window,
+ const char *type)
+{
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t *reply;
+ Ecore_X_Atom *atoms;
+ unsigned char *data;
+ int num;
+ int i;
+ uint8_t ret = 0;
+
+ cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0,
+ strlen(type), type);
+
+ if (!ecore_x_window_prop_property_get(window, ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM, 32, &data, &num))
+ {
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply) free(reply);
+ return ret;
+ }
+
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ {
+ free(data);
+ return 0;
+ }
+ atoms = (Ecore_X_Atom *)data;
+
+ for (i = 0; i < num; ++i)
+ {
+ if (reply->atom == atoms[i])
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ free(data);
+ free(reply);
+
+ return ret;
+}
+
+/* FIXME: round trip (InternAtomGet request) */
+
+/**
+ * Set the type.
+ * @param window Unused.
+ * @param type The type to set
+ * @param on 0 or non 0...
+ *
+ * Set the type.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dnd_type_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_dnd_type_get_fetch(), which gets the reply.
+ */
+EAPI void
+ecore_x_dnd_type_set(Ecore_X_Window window,
+ const char *type,
+ int on)
+{
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t *reply;
+ Ecore_X_Atom *oldset = NULL;
+ Ecore_X_Atom *newset = NULL;
+ unsigned char *data = NULL;
+ unsigned char *old_data = NULL;
+ Ecore_X_Atom atom;
+ int i, j = 0, num = 0;
+
+ cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0,
+ strlen(type), type);
+
+ atom = ecore_x_atom_get(type);
+ if (!ecore_x_window_prop_property_get(window, ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM,
+ 32, &old_data, &num))
+ {
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply) free(reply);
+ return;
+ }
+ oldset = (Ecore_X_Atom *)old_data;
+
+ if (on)
+ {
+ if (ecore_x_dnd_type_isset(window, type))
+ {
+ free(old_data);
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply) free(reply);
+ return;
+ }
+ data = calloc(num + 1, sizeof(Ecore_X_Atom));
+ if (!data)
+ {
+ free(old_data);
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply) free(reply);
+ return;
+ }
+ newset = (Ecore_X_Atom *)data;
+
+ for (i = 0; i < num; i++)
+ newset[i + 1] = oldset[i];
+ /* prepend the new type */
+
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ {
+ free(old_data);
+ return;
+ }
+ newset[0] = reply->atom;
+ free(reply);
+
+ ecore_x_window_prop_property_set(window,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM,
+ 32, data, num + 1);
+ }
+ else
+ {
+ if (!ecore_x_dnd_type_isset(window, type))
+ {
+ free(old_data);
+ return;
+ }
+ newset = calloc(num - 1, sizeof(Ecore_X_Atom));
+ if (!newset)
+ {
+ free(old_data);
+ return;
+ }
+ data = (unsigned char *)newset;
+ for (i = 0; i < num; i++)
+ if (oldset[i] != atom)
+ newset[j++] = oldset[i];
+
+ ecore_x_window_prop_property_set(window,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM,
+ 32, data, num - 1);
+ }
+
+ free(oldset);
+ free(newset);
+}
+
+/* FIXME: round trips, but I don't think we can do much, here */
+
+/**
+ * Set the types.
+ * @param window Unused.
+ * @param types The types to set
+ * @param num_types The number of types
+ *
+ * Set the types.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dnd_type_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_dnd_type_get_fetch(), which gets the reply.
+ */
+EAPI void
+ecore_x_dnd_types_set(Ecore_X_Window window,
+ const char **types,
+ unsigned int num_types)
+{
+ Ecore_X_Atom *newset = NULL;
+ void *data = NULL;
+ uint32_t i;
+
+ if (!num_types)
+ {
+ ecore_x_window_prop_property_del(window, ECORE_X_ATOM_XDND_TYPE_LIST);
+ }
+ else
+ {
+ xcb_intern_atom_cookie_t *cookies;
+ xcb_intern_atom_reply_t *reply;
+
+ cookies = (xcb_intern_atom_cookie_t *)malloc(sizeof(xcb_intern_atom_cookie_t));
+ if (!cookies) return;
+ for (i = 0; i < num_types; i++)
+ cookies[i] = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0,
+ strlen(types[i]), types[i]);
+ data = calloc(num_types, sizeof(Ecore_X_Atom));
+ if (!data)
+ {
+ for (i = 0; i < num_types; i++)
+ {
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], NULL);
+ if (reply) free(reply);
+ }
+ free(cookies);
+ return;
+ }
+ newset = data;
+ for (i = 0; i < num_types; i++)
+ {
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], NULL);
+ if (reply)
+ {
+ newset[i] = reply->atom;
+ free(reply);
+ }
+ else
+ newset[i] = XCB_NONE;
+ }
+ free(cookies);
+ ecore_x_window_prop_property_set(window, ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM, 32, data, num_types);
+ free(data);
+ }
+}
+
+Ecore_X_DND_Source *
+_ecore_x_dnd_source_get(void)
+{
+ return _source;
+}
+
+Ecore_X_DND_Target *
+_ecore_x_dnd_target_get(void)
+{
+ return _target;
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param source Window whose properties are requested.
+ */
+EAPI void
+ecore_x_dnd_begin_prefetch(Ecore_X_Window source)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ source ? source : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ ECORE_X_ATOM_XDND_AWARE,
+ ECORE_X_ATOM_ATOM,
+ 0, LONG_MAX);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_dnd_begin_prefetch().
+ */
+EAPI void
+ecore_x_dnd_begin_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/* FIXME: round trip */
+
+/**
+ * Begins the DnD.
+ * @param source Unused.
+ * @param data The data.
+ * @param size The size of the data.
+ * @return 0 on failure, 1 otherwise.
+ *
+ * Begins the DnD. Returns 0 on failure, 1 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dnd_begin_prefetch(), which sends the GetProperty request,
+ * then ecore_x_dnd_begin_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_dnd_begin(Ecore_X_Window source,
+ unsigned char *data,
+ int size)
+{
+ ecore_x_selection_xdnd_prefetch();
+ if (!ecore_x_dnd_version_get(source))
+ {
+ ecore_x_selection_xdnd_fetch();
+ return 0;
+ }
+
+ /* Take ownership of XdndSelection */
+ ecore_x_selection_xdnd_prefetch();
+ ecore_x_selection_xdnd_fetch();
+ if (!ecore_x_selection_xdnd_set(source, data, size))
+ return 0;
+
+ _source->win = source;
+ ecore_x_window_ignore_set(_source->win, 1);
+ _source->state = ECORE_X_DND_SOURCE_DRAGGING;
+ _source->time = _ecore_xcb_event_last_time;
+ _source->prev.window = 0;
+
+ /* Default Accepted Action: ask */
+ _source->action = ECORE_X_ATOM_XDND_ACTION_COPY;
+ _source->accepted_action = XCB_NONE;
+ return 1;
+}
+
+EAPI int
+ecore_x_dnd_drop(void)
+{
+ uint8_t status = 0;
+
+ if (_source->dest)
+ {
+ xcb_client_message_event_t ev;
+
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.format = 32;
+ ev.window = _source->dest;
+
+ if (_source->will_accept)
+ {
+ ev.type = ECORE_X_ATOM_XDND_DROP;
+ ev.data.data32[0] = _source->win;
+ ev.data.data32[1] = 0;
+ ev.data.data32[2] = _source->time;
+ xcb_send_event(_ecore_xcb_conn, 0, _source->dest, 0, (const char *)&ev);
+ _source->state = ECORE_X_DND_SOURCE_DROPPED;
+ status = 1;
+ }
+ else
+ {
+ ev.type = ECORE_X_ATOM_XDND_LEAVE;
+ ev.data.data32[0] = _source->win;
+ ev.data.data32[1] = 0;
+ xcb_send_event(_ecore_xcb_conn, 0, _source->dest, 0, (const char *)&ev);
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ }
+ else
+ {
+ /* Dropping on nothing */
+ ecore_x_selection_xdnd_clear();
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ ecore_x_window_ignore_set(_source->win, 0);
+
+ _source->prev.window = 0;
+ _source->dest = XCB_NONE;
+
+ return status;
+}
+
+EAPI void
+ecore_x_dnd_send_status(int will_accept,
+ int suppress,
+ Ecore_X_Rectangle rectangle,
+ Ecore_X_Atom action)
+{
+ xcb_client_message_event_t ev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ _target->will_accept = will_accept;
+
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.format = 32;
+ ev.window = _target->source;
+ ev.type = ECORE_X_ATOM_XDND_STATUS;
+
+ ev.data.data32[0] = _target->win;
+ ev.data.data32[1] = 0;
+ if (will_accept)
+ ev.data.data32[1] |= 0x1UL;
+ if (!suppress)
+ ev.data.data32[1] |= 0x2UL;
+
+ /* Set rectangle information */
+ ev.data.data32[2] = rectangle.x;
+ ev.data.data32[2] <<= 16;
+ ev.data.data32[2] |= rectangle.y;
+ ev.data.data32[3] = rectangle.width;
+ ev.data.data32[3] <<= 16;
+ ev.data.data32[3] |= rectangle.height;
+
+ if (will_accept)
+ {
+ ev.data.data32[4] = action;
+ _target->accepted_action = action;
+ }
+ else
+ {
+ ev.data.data32[4] = XCB_NONE;
+ _target->accepted_action = action;
+ }
+
+ xcb_send_event(_ecore_xcb_conn, 0, _target->source, 0, (const char *)&ev);
+}
+
+EAPI void
+ecore_x_dnd_send_finished(void)
+{
+ xcb_client_message_event_t ev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.format = 32;
+ ev.window = _target->source;
+ ev.type = ECORE_X_ATOM_XDND_FINISHED;
+
+ ev.data.data32[0] = _target->win;
+ ev.data.data32[1] = 0;
+ ev.data.data32[2] = 0;
+ if (_target->will_accept)
+ {
+ ev.data.data32[1] |= 0x1UL;
+ ev.data.data32[2] = _target->accepted_action;
+ }
+ xcb_send_event(_ecore_xcb_conn, 0, _target->source, 0, (const char *)&ev);
+
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+}
+
+void
+ecore_x_dnd_source_action_set(Ecore_X_Atom action)
+{
+ _source->action = action;
+ if (_source->prev.window)
+ _ecore_x_dnd_drag(_source->prev.window, _source->prev.x, _source->prev.y);
+}
+
+Ecore_X_Atom
+ecore_x_dnd_source_action_get(void)
+{
+ return _source->action;
+}
+
+void
+_ecore_x_dnd_drag(Ecore_X_Window root,
+ int x,
+ int y)
+{
+ xcb_client_message_event_t ev;
+ Ecore_X_Window win;
+ Ecore_X_Window *skip;
+ int num;
+
+ if (_source->state != ECORE_X_DND_SOURCE_DRAGGING)
+ return;
+
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.format = 32;
+
+ /* Attempt to find a DND-capable window under the cursor */
+ skip = ecore_x_window_ignore_list(&num);
+// win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
+ win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num);
+ while (win)
+ {
+ xcb_query_tree_cookie_t cookie_tree;
+ xcb_query_tree_reply_t *reply_tree;
+
+ ecore_x_dnd_version_get_prefetch(win);
+ cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, win);
+
+ ecore_x_dnd_version_get_fetch();
+ /* We found the correct window ? */
+ if (ecore_x_dnd_version_get(win))
+ {
+ reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL);
+ if (reply_tree) free(reply_tree);
+ break;
+ }
+ reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL);
+ if (reply_tree)
+ {
+ win = reply_tree->parent;
+ free(reply_tree);
+ }
+ }
+
+ /* Send XdndLeave to current destination window if we have left it */
+ if ((_source->dest) && (win != _source->dest))
+ {
+ ev.window = _source->dest;
+ ev.type = ECORE_X_ATOM_XDND_LEAVE;
+ ev.data.data32[0] = _source->win;
+ ev.data.data32[1] = 0;
+
+ xcb_send_event(_ecore_xcb_conn, 0, _source->dest, 0, (const char *)&ev);
+ _source->suppress = 0;
+ }
+
+ if (win)
+ {
+ int16_t x1;
+ int16_t x2;
+ int16_t y1;
+ int16_t y2;
+
+ ecore_x_dnd_version_get_prefetch(win);
+ ecore_x_dnd_type_get_prefetch(_source->win);
+
+ ecore_x_dnd_version_get_fetch();
+ if (!ecore_x_dnd_version_get(win))
+ {
+ ecore_x_dnd_type_get_fetch();
+ return;
+ }
+
+ _source->version = MIN(ECORE_X_DND_VERSION,
+ ecore_x_dnd_version_get(win));
+ if (win != _source->dest)
+ {
+ unsigned char *data;
+ Ecore_X_Atom *types;
+ int num;
+ int i;
+
+ ecore_x_dnd_type_get_fetch();
+ if (!ecore_x_window_prop_property_get(_source->win,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM,
+ 32, &data, &num))
+ return;
+
+ types = (Ecore_X_Atom *)data;
+
+ /* Entered new window, send XdndEnter */
+ ev.window = win;
+ ev.type = ECORE_X_ATOM_XDND_ENTER;
+ ev.data.data32[0] = _source->win;
+ ev.data.data32[1] = 0;
+ if (num > 3)
+ ev.data.data32[1] |= 0x1UL;
+ else
+ ev.data.data32[1] &= 0xfffffffeUL;
+ ev.data.data32[1] |= ((unsigned long) _source->version) << 24;
+
+ for (i = 2; i < 5; i++)
+ ev.data.data32[i] = 0;
+ for (i = 0; i < MIN(num, 3); ++i)
+ ev.data.data32[i + 2] = types[i];
+ free(data);
+ xcb_send_event(_ecore_xcb_conn, 0, win, 0, (const char *)&ev);
+ _source->await_status = 0;
+ _source->will_accept = 0;
+ }
+ else
+ ecore_x_dnd_type_get_fetch();
+
+ /* Determine if we're still in the rectangle from the last status */
+ x1 = _source->rectangle.x;
+ x2 = _source->rectangle.x + _source->rectangle.width;
+ y1 = _source->rectangle.y;
+ y2 = _source->rectangle.y + _source->rectangle.height;
+
+ if ((!_source->await_status) ||
+ (!_source->suppress) ||
+ ((x < x1) || (x > x2) || (y < y1) || (y > y2)))
+ {
+ ev.window = win;
+ ev.type = ECORE_X_ATOM_XDND_POSITION;
+ ev.data.data32[0] = _source->win;
+ ev.data.data32[1] = 0; /* Reserved */
+ ev.data.data32[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ ev.data.data32[3] = _source->time; /* Version 1 */
+ ev.data.data32[4] = _source->action; /* Version 2, Needs to be pre-set */
+ xcb_send_event(_ecore_xcb_conn, 0, win, 0, (const char *)&ev);
+
+ _source->await_status = 1;
+ }
+ }
+
+ _source->prev.x = x;
+ _source->prev.y = y;
+ _source->prev.window = root;
+ _source->dest = win;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions
+ *
+ * Functions related to the X DPMS extension.
+ */
+
+
+#ifdef ECORE_XCB_DPMS
+static int _dpms_available = 0;
+static xcb_dpms_get_version_cookie_t _ecore_xcb_dpms_init_cookie;
+#endif /* ECORE_XCB_DPMS */
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_dpms_init and
+ _ecore_xcb_dpms_init_finalize. The first one gets the cookies and
+ the second one gets the replies. */
+
+void
+_ecore_x_dpms_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_DPMS
+ if (reply && (reply->present))
+ _ecore_xcb_dpms_init_cookie = xcb_dpms_get_version_unchecked(_ecore_xcb_conn, 0, 0);
+#endif /* ECORE_XCB_DPMS */
+}
+
+void
+_ecore_x_dpms_init_finalize(void)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_version_reply_t *reply;
+
+ reply = xcb_dpms_get_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_dpms_init_cookie, NULL);
+
+ if (reply)
+ {
+ if (reply->server_major_version >= 1)
+ _dpms_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Checks if the DPMS extension is available or not.
+ * @return @c 1 if the DPMS extension is available, @c 0 otherwise.
+ *
+ * Return 1 if the X server supports the DPMS Extension version 1.0,
+ * 0 otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_query(void)
+{
+#ifdef ECORE_XCB_DPMS
+ return _dpms_available;
+#else
+ return 0;
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Sends the DPMSCapable request.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_capable_get_prefetch(void)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_capable_cookie_t cookie;
+
+ cookie = xcb_dpms_capable_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Gets the reply of the DPMSCapable request sent by ecore_x_dpms_capable_get_prefetch().
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_capable_get_fetch(void)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_capable_cookie_t cookie;
+ xcb_dpms_capable_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_dpms_capable_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Checks if the X server is capable of DPMS.
+ * @return @c 1 if the X server is capable of DPMS, @c 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_capable_get_prefetch(), which sends the DPMSCapable request,
+ * then ecore_x_dpms_capable_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_capable_get(void)
+{
+ int capable = 0;
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_capable_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ capable = reply->capable;
+#endif /* ECORE_XCB_DPMS */
+
+ return capable;
+}
+
+
+/**
+ * Sends the DPMSInfo request.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_enable_get_prefetch(void)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_info_cookie_t cookie;
+
+ cookie = xcb_dpms_info_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Gets the reply of the DPMSInfo request sent by ecore_x_dpms_enable_get_prefetch().
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_enable_get_fetch(void)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_info_cookie_t cookie;
+ xcb_dpms_info_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_dpms_info_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Checks the DPMS state of the display.
+ * @return @c 1 if DPMS is enabled, @c 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_enapable_get_prefetch(), which sends the DPMSInfo request,
+ * then ecore_x_dpms_enapable_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_enable_get(void)
+{
+ int enable = 0;
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_info_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ enable = reply->state;
+#endif /* ECORE_XCB_DPMS */
+
+ return enable;
+}
+
+
+/**
+ * Sets the DPMS state of the display.
+ * @param enabled @c 0 to disable DPMS characteristics of the server, enable it otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_enabled_set(int enabled)
+{
+#ifdef ECORE_XCB_DPMS
+ if (enabled)
+ xcb_dpms_enable(_ecore_xcb_conn);
+ else
+ xcb_dpms_disable(_ecore_xcb_conn);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Sets the timeouts. The values are in unit of seconds.
+ * @param standby Amount of time of inactivity before standby mode will be invoked.
+ * @param suspend Amount of time of inactivity before the screen is placed into suspend mode.
+ * @param off Amount of time of inactivity before the monitor is shut off.
+ * @return Returns always 1.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_timeouts_set(unsigned int standby,
+ unsigned int suspend,
+ unsigned int off)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_set_timeouts(_ecore_xcb_conn, standby, suspend, off);
+#endif /* ECORE_XCB_DPMS */
+
+ return 1;
+}
+
+
+/**
+ * Sends the DPMSGetTimeouts request.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeouts_get_prefetch(void)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_cookie_t cookie;
+
+ cookie = xcb_dpms_get_timeouts_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Gets the reply of the DPMSGetTimeouts request sent by ecore_x_dpms_timeouts_get_prefetch().
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeouts_get_fetch(void)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_cookie_t cookie;
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_dpms_get_timeouts_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Gets the timeouts. The values are in unit of seconds.
+ * @param standby Amount of time of inactivity before standby mode will be invoked.
+ * @param suspend Amount of time of inactivity before the screen is placed into suspend mode.
+ * @param off Amount of time of inactivity before the monitor is shut off.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeouts_get(unsigned int *standby,
+ unsigned int *suspend,
+ unsigned int *off)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (reply)
+ {
+ if (standby) *standby = reply->standby_timeout;
+ if (suspend) *suspend = reply->suspend_timeout;
+ if (off) *off = 0;
+ }
+ else
+#endif /* ECORE_XCB_DPMS */
+ {
+ if (standby) *standby = 0;
+ if (suspend) *suspend = 0;
+ if (off) *off = 0;
+ }
+}
+
+
+/**
+ * Returns the amount of time of inactivity before standby mode is invoked.
+ * @return The standby timeout value.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request,
+ * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_standby_get(void)
+{
+ int standby = 0;
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ standby = reply->standby_timeout;
+#endif /* ECORE_XCB_DPMS */
+
+ return standby;
+}
+
+
+/**
+ * Returns the amount of time of inactivity before the second level of
+ * power saving is invoked.
+ * @return The suspend timeout value.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request,
+ * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_suspend_get(void)
+{
+ int suspend = 0;;
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ suspend = reply->suspend_timeout;
+#endif /* ECORE_XCB_DPMS */
+
+ return suspend;
+}
+
+
+/**
+ * Returns the amount of time of inactivity before the third and final
+ * level of power saving is invoked.
+ * @return The off timeout value.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request,
+ * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_off_get(void)
+{
+ int off = 0;
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ off = reply->off_timeout;
+#endif /* ECORE_XCB_DPMS */
+
+ return off;
+}
+
+
+/**
+ * Sets the standby timeout (in unit of seconds).
+ * @param new_standby Amount of time of inactivity before standby mode will be invoked.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request,
+ * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_standby_set(unsigned int new_standby)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ xcb_dpms_set_timeouts(_ecore_xcb_conn,
+ new_standby,
+ reply->suspend_timeout,
+ reply->off_timeout);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Sets the suspend timeout (in unit of seconds).
+ * @param suspend Amount of time of inactivity before the screen is placed into suspend mode.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request,
+ * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_suspend_set(unsigned int new_suspend)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ xcb_dpms_set_timeouts(_ecore_xcb_conn,
+ reply->standby_timeout,
+ new_suspend,
+ reply->off_timeout);
+#endif /* ECORE_XCB_DPMS */
+}
+
+
+/**
+ * Sets the off timeout (in unit of seconds).
+ * @param off Amount of time of inactivity before the monitor is shut off.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_dpms_timeouts_get_prefetch(), which sends the DPMSGetTimeouts request,
+ * then ecore_x_dpms_timeouts_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_off_set(unsigned int new_off)
+{
+#ifdef ECORE_XCB_DPMS
+ xcb_dpms_get_timeouts_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ xcb_dpms_set_timeouts(_ecore_xcb_conn,
+ reply->standby_timeout,
+ reply->suspend_timeout,
+ new_off);
+#endif /* ECORE_XCB_DPMS */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+#include <xcb/xcb.h>
+
+
+/**
+ * @defgroup Ecore_X_Drawable_Group X Drawable Functions
+ *
+ * Functions that operate on drawables.
+ */
+
+
+/**
+ * Sends the GetGeometry request.
+ * @param drawable Drawable whose characteristics are sought.
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI void
+ecore_x_drawable_geometry_get_prefetch(Ecore_X_Drawable drawable)
+{
+ xcb_get_geometry_cookie_t cookie;
+
+ cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, drawable);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetGeometry request sent by ecore_x_atom_get_prefetch().
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI void
+ecore_x_drawable_geometry_get_fetch(void)
+{
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+
+/**
+ * Retrieves the geometry of the given drawable.
+ * @param drawable Unused.
+ * @param x Pointer to an integer into which the X position is to be stored.
+ * @param y Pointer to an integer into which the Y position is to be stored.
+ * @param width Pointer to an integer into which the width is to be stored.
+ * @param height Pointer to an integer into which the height is to be stored.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request,
+ * then ecore_x_drawable_geometry_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI void
+ecore_x_drawable_geometry_get(Ecore_X_Drawable drawable __UNUSED__,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+ xcb_get_geometry_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ {
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = 0;
+ if (height) *height = 0;
+ return;
+ }
+
+ if (x) *x = reply->x;
+ if (y) *y = reply->y;
+ if (width) *width = reply->width;
+ if (height) *height = reply->height;
+}
+
+
+/**
+ * Retrieves the width of the border of the given drawable.
+ * @param drawable Unused.
+ * @return The border width of the given drawable.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request,
+ * then ecore_x_drawable_geometry_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI int
+ecore_x_drawable_border_width_get(Ecore_X_Drawable drawable __UNUSED__)
+{
+ xcb_get_geometry_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ return reply->border_width;
+}
+
+
+/**
+ * Retrieves the depth of the given drawable.
+ * @param drawable Unused.
+ * @return The depth of the given drawable.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request,
+ * then ecore_x_drawable_geometry_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI int
+ecore_x_drawable_depth_get(Ecore_X_Drawable drawable __UNUSED__)
+{
+ xcb_get_geometry_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ return reply->depth;
+}
+
+/**
+ * Fill the specified rectangle on a drawable.
+ * @param d The given drawable.
+ * @param gc The graphic context that controls the fill rules.
+ * @param x The X coordinate of the top-left corner of the rectangle.
+ * @param y The Y coordinate of the top-left corner of the rectangle.
+ * @param width The width of the rectangle.
+ * @param height The height of the rectangle.
+ */
+EAPI void
+ecore_x_drawable_rectangle_fill(Ecore_X_Drawable d, Ecore_X_GC gc, int x, int y, int width, int height)
+{
+ xcb_rectangle_t rectangle;
+
+ rectangle.x = x;
+ rectangle.y = y;
+ rectangle.width = width;
+ rectangle.height = height;
+ xcb_poly_fill_rectangle(_ecore_xcb_conn, d, gc, 1, &rectangle);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * OLD E hints
+ */
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+EAPI void
+ecore_x_e_frame_size_set(Ecore_X_Window window,
+ int fl,
+ int fr,
+ int ft,
+ int fb)
+{
+ uint32_t frames[4];
+
+ frames[0] = fl;
+ frames[1] = fr;
+ frames[2] = ft;
+ frames[3] = fb;
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_E_FRAME_SIZE, ECORE_X_ATOM_CARDINAL, 32,
+ 4, (const void *)frames);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+/** OpenBSD does not define CODESET
+ * FIXME ??
+ */
+
+#ifndef CODESET
+#define CODESET "INVALID"
+#endif
+
+#if 0
+static void _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_title_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev);
+#endif
+
+static Ecore_X_Window _ecore_xcb_mouse_down_last_window = 0;
+static Ecore_X_Window _ecore_xcb_mouse_down_last_last_window = 0;
+static Ecore_X_Window _ecore_xcb_mouse_down_last_event_window = 0;
+static Ecore_X_Window _ecore_xcb_mouse_down_last_last_event_window = 0;
+static Ecore_X_Time _ecore_xcb_mouse_down_last_time = 0;
+static Ecore_X_Time _ecore_xcb_mouse_down_last_last_time = 0;
+static int _ecore_xcb_mouse_up_count = 0;
+static int _ecore_xcb_mouse_down_did_triple = 0;
+static int _ecore_xcb_last_event_mouse_move = 0;
+static Ecore_Event *_ecore_xcb_last_event_mouse_move_event = NULL;
+
+static void
+_ecore_x_event_free_mouse_move(void *data __UNUSED__, void *ev)
+{
+ Ecore_Event_Mouse_Move *e;
+
+ e = ev;
+ if (_ecore_xcb_last_event_mouse_move)
+ {
+ _ecore_xcb_last_event_mouse_move_event = NULL;
+ _ecore_xcb_last_event_mouse_move = 0;
+ }
+ free(e);
+}
+
+
+/* FIXME: roundtrip */
+EAPI void
+ecore_x_event_mask_set(Ecore_X_Window window,
+ Ecore_X_Event_Mask mask)
+{
+ xcb_get_window_attributes_cookie_t cookie;
+ xcb_get_window_attributes_reply_t *reply;
+ uint32_t value_list;
+
+ if (!window)
+ window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
+ reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return;
+
+ value_list = mask | reply->your_event_mask;
+ xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
+ free(reply);
+}
+
+/* FIXME: roundtrip */
+EAPI void
+ecore_x_event_mask_unset(Ecore_X_Window window,
+ Ecore_X_Event_Mask mask)
+{
+ xcb_get_window_attributes_cookie_t cookie;
+ xcb_get_window_attributes_reply_t *reply;
+ uint32_t value_list;
+
+ if (!window)
+ window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
+ reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply) return;
+
+ value_list = reply->your_event_mask & ~mask;
+ xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
+ free(reply);
+}
+
+#if 0
+static void
+_ecore_x_event_free_window_prop_name_class_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Name_Class_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ if (e->clas) free(e->clas);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_title_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Title_Change *e;
+
+ e = ev;
+ if (e->title) free(e->title);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
+
+ e = ev;
+ if (e->title) free(e->title);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+#endif
+
+static void
+_ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Xdnd_Enter *e;
+ int i;
+
+ e = ev;
+ for (i = 0; i < e->num_types; i++)
+ free(e->types[i]);
+ free(e->types);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Selection_Notify *e;
+ Ecore_X_Selection_Data *sel;
+
+ e = ev;
+ sel = e->data;
+ if (sel->free)
+ sel->free(sel);
+ free(e->target);
+ free(e);
+}
+
+static unsigned int
+_ecore_x_event_modifiers(unsigned int state)
+{
+ unsigned int modifiers = 0;
+
+ if (state & ECORE_X_MODIFIER_SHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (state & ECORE_X_MODIFIER_CTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if (state & ECORE_X_MODIFIER_ALT) modifiers |= ECORE_EVENT_MODIFIER_ALT;
+ if (state & ECORE_X_MODIFIER_WIN) modifiers |= ECORE_EVENT_MODIFIER_WIN;
+ if (state & ECORE_X_LOCK_SCROLL) modifiers |= ECORE_EVENT_LOCK_SCROLL;
+ if (state & ECORE_X_LOCK_NUM) modifiers |= ECORE_EVENT_LOCK_NUM;
+ if (state & ECORE_X_LOCK_CAPS) modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ return modifiers;
+}
+
+static void
+_ecore_mouse_move(unsigned int timestamp, unsigned int xmodifiers,
+ int x, int y,
+ int x_root, int y_root,
+ unsigned int event_window,
+ unsigned int window,
+ unsigned int root_win,
+ int same_screen)
+{
+ Ecore_Event_Mouse_Move *e;
+ Ecore_Event *event;
+
+ e = malloc(sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return ;
+
+ e->window = window;
+ e->root_window = root_win;
+ e->timestamp = timestamp;
+ e->same_screen = same_screen;
+ e->event_window = event_window;
+
+ e->modifiers = _ecore_x_event_modifiers(xmodifiers);
+ e->x = x;
+ e->y = y;
+ e->root.x = x_root;
+ e->root.y = y_root;
+
+ event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _ecore_x_event_free_mouse_move, NULL);
+
+ _ecore_xcb_event_last_time = timestamp;
+ _ecore_xcb_event_last_window = window;
+ _ecore_xcb_event_last_root_x = x_root;
+ _ecore_xcb_event_last_root_y = y_root;
+
+ _ecore_xcb_last_event_mouse_move_event = event;
+}
+
+static void
+_ecore_key_press(int event,
+ xcb_generic_event_t *ev)
+{
+ /*
+ Ecore_Event_Key *e;
+ const char *compose = NULL;
+ char *tmp = NULL;
+ char *keyname;
+ char *key;
+ char keyname_buffer[256];
+ char compose_buffer[256];
+ KeySym sym;
+ XComposeStatus status;
+ int val;
+
+ _ecore_xcb_last_event_mouse_move = 0;
+ keyname = XKeysymToString(XKeycodeToKeysym(xevent->display,
+ xevent->keycode, 0));
+ if (!keyname)
+ {
+ snprintf(keyname_buffer, sizeof(keyname_buffer), "Keycode-%i", xevent->keycode);
+ keyname = keyname_buffer;
+ if (!keyname) return ;
+ }
+
+ sym = 0;
+ key = NULL;
+ compose = NULL;
+ if (_ecore_x_ic)
+ {
+ Status mbstatus;
+#ifdef X_HAVE_UTF8_STRING
+ val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus);
+#else
+ val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus);
+#endif
+ if (mbstatus == XBufferOverflow)
+ {
+ tmp = malloc(sizeof (char) * (val + 1));
+ if (!tmp) return ;
+
+ compose = tmp;
+
+#ifdef X_HAVE_UTF8_STRING
+ val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus);
+#else
+ val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus);
+#endif
+ if (val > 0)
+ {
+ tmp[val] = 0;
+
+#ifndef X_HAVE_UTF8_STRING
+ compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", tmp);
+ free(tmp);
+ tmp = compose;
+#endif
+ }
+ else compose = NULL;
+ }
+ else
+ if (val > 0)
+ {
+ compose_buffer[val] = 0;
+#ifdef X_HAVE_UTF8_STRING
+ compose = compose_buffer;
+#else
+ compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
+ tmp = compose;
+#endif
+ }
+ }
+ else
+ {
+ val = XLookupString(xevent, compose_buffer, sizeof(compose_buffer), &sym, &status);
+ if (val > 0)
+ {
+ compose_buffer[val] = 0;
+ compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
+ tmp = compose;
+ }
+ }
+
+ key = XKeysymToString(sym);
+ if (!key) key = keyname;
+ if (!key) goto on_error;
+
+ e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + (compose ? strlen(compose) : 0) + 3);
+ if (!e) goto on_error;
+
+ e->keyname = (char*) (e + 1);
+ e->key = e->keyname + strlen(keyname) + 1;
+ e->compose = (compose) ? e->key + strlen(key) + 1 : NULL;
+ e->string = e->compose;
+
+ strcpy((char *) e->keyname, keyname);
+ strcpy((char *) e->key, key);
+ if (compose) strcpy((char *) e->compose, compose);
+
+ e->modifiers = _ecore_x_event_modifiers(xevent->state);
+
+ e->timestamp = xevent->time;
+ e->window = xevent->subwindow ? xevent->subwindow : xevent->window;
+ e->event_window = xevent->window;
+ e->same_screen = xevent->same_screen;
+ e->root_window = xevent->root;
+
+ ecore_event_add(event, e, NULL, NULL);
+
+ _ecore_xcb_event_last_time = e->timestamp;
+
+ on_error:
+ if (tmp) free(tmp);
+ */
+}
+
+static Ecore_Event_Mouse_Button*
+_ecore_mouse_button(int event,
+ unsigned int timestamp, unsigned int xmodifiers,
+ unsigned int buttons,
+ int x, int y,
+ int x_root, int y_root,
+ unsigned int event_window,
+ unsigned int window,
+ unsigned int root_win,
+ int same_screen)
+{
+ Ecore_Event_Mouse_Button *e;
+
+ e = malloc(sizeof(Ecore_Event_Mouse_Button));
+ if (!e) return NULL;
+
+ e->window = window;
+ e->root_window = root_win;
+ e->timestamp = timestamp;
+ e->same_screen = same_screen;
+ e->event_window = event_window;
+
+ e->buttons = buttons;
+ e->modifiers = _ecore_x_event_modifiers(xmodifiers);
+ e->double_click = 0;
+ e->triple_click = 0;
+ e->x = x;
+ e->y = y;
+ e->root.x = x_root;
+ e->root.y = y_root;
+
+ if (event_window == window)
+ {
+ if (((int)(timestamp - _ecore_xcb_mouse_down_last_time) <=
+ (int)(1000 * _ecore_xcb_double_click_time)) &&
+ (window == _ecore_xcb_mouse_down_last_window) &&
+ (event_window == _ecore_xcb_mouse_down_last_event_window)
+ )
+ e->double_click = 1;
+ if (((int)(timestamp - _ecore_xcb_mouse_down_last_last_time) <=
+ (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
+ (window == _ecore_xcb_mouse_down_last_window) &&
+ (window == _ecore_xcb_mouse_down_last_last_window) &&
+ (event_window == _ecore_xcb_mouse_down_last_event_window) &&
+ (event_window == _ecore_xcb_mouse_down_last_last_event_window)
+ )
+ {
+ e->triple_click = 1;
+ _ecore_xcb_mouse_down_did_triple = 1;
+ }
+ else
+ _ecore_xcb_mouse_down_did_triple = 0;
+ }
+
+ if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN
+ && !e->double_click
+ && !e->triple_click)
+ _ecore_xcb_mouse_up_count = 0;
+
+ _ecore_xcb_event_last_time = e->timestamp;
+ _ecore_xcb_event_last_window = e->window;
+ _ecore_xcb_event_last_root_x = x_root;
+ _ecore_xcb_event_last_root_y = y_root;
+
+ ecore_event_add(event, e, NULL, NULL);
+
+ return e;
+}
+
+void
+_ecore_x_event_handle_any_event(xcb_generic_event_t *event)
+{
+ xcb_generic_event_t* ev = malloc(sizeof(xcb_generic_event_t));
+ memcpy(ev, event, sizeof(xcb_generic_event_t));
+
+ ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
+}
+
+/* FIXME: handle this event */
+void
+_ecore_x_event_handle_key_press(xcb_generic_event_t *event)
+{
+ _ecore_key_press(ECORE_EVENT_KEY_DOWN, event);
+
+ free(event);
+}
+
+/* FIXME: handle this event */
+void
+_ecore_x_event_handle_key_release(xcb_generic_event_t *event)
+{
+ _ecore_key_press(ECORE_EVENT_KEY_DOWN, event);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_button_press(xcb_generic_event_t *event)
+{
+ xcb_button_press_event_t *ev;
+ int i;
+
+ ev = (xcb_button_press_event_t *)event;
+ if ((ev->detail > 3) && (ev->detail < 8))
+ {
+ Ecore_Event_Mouse_Wheel *e;
+
+ e = malloc(sizeof(Ecore_Event_Mouse_Wheel));
+ if (!e) return;
+
+ e->timestamp = ev->time;
+ e->modifiers = _ecore_x_event_modifiers(ev->state);
+ switch (ev->detail)
+ {
+ case 4: e->direction = 0; e->z = -1; break;
+ case 5: e->direction = 0; e->z = 1; break;
+ case 6: e->direction = 1; e->z = -1; break;
+ case 7: e->direction = 1; e->z = 1; break;
+ default: e->direction = 0; e->z = 0; break;
+ }
+
+ e->x = ev->event_x;
+ e->y = ev->event_y;
+ e->root.x = ev->root_x;
+ e->root.y = ev->root_y;
+
+ if (ev->child)
+ e->window = ev->child;
+ else
+ e->window = ev->event;
+
+ e->event_window = ev->event;
+ e->same_screen = ev->same_screen;
+ e->root_window = ev->root;
+ _ecore_xcb_event_last_time = e->timestamp;
+ _ecore_xcb_event_last_window = e->window;
+ _ecore_xcb_event_last_root_x = e->root.x;
+ _ecore_xcb_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == ev->event) ||
+ (_ecore_window_grabs[i] == ev->child))
+ {
+ int replay = 0;
+
+ if (_ecore_window_grab_replay_func)
+ replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
+ ECORE_EVENT_MOUSE_WHEEL,
+ e);
+ /* FIXME: xcb_key_press_event_t does not save the */
+ /* connection. So I use the current one */
+ if (replay)
+ xcb_allow_events(_ecore_xcb_conn,
+ XCB_ALLOW_REPLAY_POINTER,
+ ev->time);
+ else
+ xcb_allow_events(_ecore_xcb_conn,
+ XCB_ALLOW_ASYNC_POINTER,
+ ev->time);
+ break;
+ }
+ }
+ }
+ else
+ {
+ {
+ _ecore_mouse_move(ev->time, ev->state,
+ ev->event_x, ev->event_y,
+ ev->root_x, ev->root_y,
+ ev->event,
+ (ev->child ? ev->child : ev->event),
+ ev->root,
+ ev->same_screen);
+ }
+ {
+ Ecore_Event_Mouse_Button *e;
+ Ecore_X_Window event_window;
+ Ecore_X_Window child_window;
+
+ if (_ecore_xcb_mouse_down_did_triple)
+ {
+ _ecore_xcb_mouse_down_last_window = 0;
+ _ecore_xcb_mouse_down_last_last_window = 0;
+ _ecore_xcb_mouse_down_last_event_window = 0;
+ _ecore_xcb_mouse_down_last_last_event_window = 0;
+ _ecore_xcb_mouse_down_last_time = 0;
+ _ecore_xcb_mouse_down_last_last_time = 0;
+ }
+ event_window = ev->child;
+ child_window = ev->child ? ev->child : ev->event;
+
+ e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ ev->time, ev->state,
+ ev->detail,
+ ev->event_x, ev->event_y,
+ ev->root_x, ev->root_y,
+ event_window, child_window,
+ ev->root, ev->same_screen);
+
+ if (!e) return;
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == ev->event) ||
+ (_ecore_window_grabs[i] == ev->child))
+ {
+ int replay = 0;
+
+ if (_ecore_window_grab_replay_func)
+ replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
+ ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ e);
+ /* FIXME: xcb_key_press_event_t does not save the */
+ /* connection. So I use the current one */
+ if (replay)
+ xcb_allow_events(_ecore_xcb_conn,
+ XCB_ALLOW_REPLAY_POINTER,
+ ev->time);
+ else
+ xcb_allow_events(_ecore_xcb_conn,
+ XCB_ALLOW_ASYNC_POINTER,
+ ev->time);
+ break;
+ }
+ }
+ if (child_window == event_window)
+ {
+ if (!_ecore_xcb_mouse_down_did_triple)
+ {
+ _ecore_xcb_mouse_down_last_last_window = _ecore_xcb_mouse_down_last_window;
+ if (ev->child)
+ _ecore_xcb_mouse_down_last_window = ev->child;
+ else
+ _ecore_xcb_mouse_down_last_window = ev->event;
+ _ecore_xcb_mouse_down_last_last_event_window = _ecore_xcb_mouse_down_last_event_window;
+ _ecore_xcb_mouse_down_last_event_window = ev->event;
+ _ecore_xcb_mouse_down_last_last_time = _ecore_xcb_mouse_down_last_time;
+ _ecore_xcb_mouse_down_last_time = ev->time;
+ }
+ }
+ }
+ }
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_button_release(xcb_generic_event_t *event)
+{
+ xcb_button_release_event_t *ev;
+
+ ev = (xcb_button_release_event_t *)event;
+ _ecore_xcb_last_event_mouse_move = 0;
+ /* filter out wheel buttons */
+ if ((ev->detail <= 3) || (ev->detail > 7))
+ {
+ _ecore_mouse_move(ev->time, ev->state,
+ ev->event_x, ev->event_y,
+ ev->root_x, ev->root_y,
+ ev->event,
+ (ev->child ? ev->child : ev->event),
+ ev->root,
+ ev->same_screen);
+
+ _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
+ ev->time, ev->state,
+ ev->detail,
+ ev->event_x, ev->event_y,
+ ev->root_x, ev->root_y,
+ ev->event,
+ (ev->child ? ev->child : ev->event),
+ ev->root,
+ ev->same_screen);
+ }
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_motion_notify(xcb_generic_event_t *event)
+{
+ xcb_motion_notify_event_t *ev;
+
+ ev = (xcb_motion_notify_event_t *)event;
+ if (_ecore_xcb_last_event_mouse_move)
+ {
+ ecore_event_del(_ecore_xcb_last_event_mouse_move_event);
+ _ecore_xcb_last_event_mouse_move = 0;
+ _ecore_xcb_last_event_mouse_move_event = NULL;
+ }
+
+ _ecore_mouse_move(ev->time, ev->state,
+ ev->event_x, ev->event_y,
+ ev->root_x, ev->root_y,
+ ev->event,
+ (ev->child ? ev->child : ev->event),
+ ev->root,
+ ev->same_screen);
+
+ _ecore_xcb_last_event_mouse_move = 1;
+
+ /* Xdnd handling */
+ _ecore_x_dnd_drag(ev->root, ev->root_x, ev->root_y);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_enter_notify(xcb_generic_event_t *event)
+{
+ xcb_enter_notify_event_t *ev;
+
+ ev = (xcb_enter_notify_event_t *)event;
+ _ecore_xcb_last_event_mouse_move = 0;
+
+ {
+ _ecore_mouse_move(ev->time, ev->state,
+ ev->event_x, ev->event_y,
+ ev->root_x, ev->root_y,
+ ev->event,
+ (ev->child ? ev->child : ev->event),
+ ev->root,
+ ev->same_screen_focus);
+ }
+ {
+ Ecore_X_Event_Mouse_In *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
+ if (!e) return;
+ e->modifiers = _ecore_x_event_modifiers(ev->state);
+ e->x = ev->event_x;
+ e->y = ev->event_y;
+ e->root.x = ev->root_x;
+ e->root.y = ev->root_y;
+ if (ev->child) e->win = ev->child;
+ else e->win = ev->event;
+ e->same_screen = ev->same_screen_focus;
+ e->root_win = ev->root;
+ e->event_win = ev->event;
+ switch (ev->mode) {
+ case XCB_NOTIFY_MODE_NORMAL:
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ break;
+ case XCB_NOTIFY_MODE_GRAB:
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ break;
+ case XCB_NOTIFY_MODE_UNGRAB:
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ break;
+ default:
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ break;
+ }
+ switch (ev->detail) {
+ case XCB_NOTIFY_DETAIL_ANCESTOR:
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ break;
+ case XCB_NOTIFY_DETAIL_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ break;
+ case XCB_NOTIFY_DETAIL_INFERIOR:
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ break;
+ default:
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ break;
+ }
+ e->time = ev->time;
+ _ecore_xcb_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
+ }
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_leave_notify(xcb_generic_event_t *event)
+{
+ xcb_leave_notify_event_t *ev;
+
+ ev = (xcb_leave_notify_event_t *)event;
+ _ecore_xcb_last_event_mouse_move = 0;
+
+ {
+ _ecore_mouse_move(ev->time, ev->state,
+ ev->event_x, ev->event_y,
+ ev->root_x, ev->root_y,
+ ev->event,
+ (ev->child ? ev->child : ev->event),
+ ev->root,
+ ev->same_screen_focus);
+ }
+ {
+ Ecore_X_Event_Mouse_Out *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
+ if (!e) return;
+ e->modifiers = _ecore_x_event_modifiers(ev->state);
+ e->x = ev->event_x;
+ e->y = ev->event_y;
+ e->root.x = ev->root_x;
+ e->root.y = ev->root_y;
+ if (ev->child) e->win = ev->child;
+ else e->win = ev->event;
+ e->same_screen = ev->same_screen_focus;
+ e->root_win = ev->root;
+ e->event_win = ev->event;
+ switch (ev->mode) {
+ case XCB_NOTIFY_MODE_NORMAL:
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ break;
+ case XCB_NOTIFY_MODE_GRAB:
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ break;
+ case XCB_NOTIFY_MODE_UNGRAB:
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ break;
+ default:
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ break;
+ }
+ switch (ev->detail) {
+ case XCB_NOTIFY_DETAIL_ANCESTOR:
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ break;
+ case XCB_NOTIFY_DETAIL_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ break;
+ case XCB_NOTIFY_DETAIL_INFERIOR:
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ break;
+ default:
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ break;
+ }
+ e->time = ev->time;
+ _ecore_xcb_event_last_time = e->time;
+ _ecore_xcb_event_last_window = e->win;
+ _ecore_xcb_event_last_root_x = e->root.x;
+ _ecore_xcb_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
+ }
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_focus_in(xcb_generic_event_t *event)
+{
+ xcb_focus_in_event_t *ev;
+ Ecore_X_Event_Window_Focus_In *e;
+
+ ev = (xcb_focus_in_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
+ if (!e) return;
+ e->win = ev->event;
+ switch (ev->mode) {
+ case XCB_NOTIFY_MODE_NORMAL:
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ break;
+ case XCB_NOTIFY_MODE_GRAB:
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ break;
+ case XCB_NOTIFY_MODE_UNGRAB:
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ break;
+ case XCB_NOTIFY_MODE_WHILE_GRABBED:
+ e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ break;
+ }
+ switch (ev->detail) {
+ case XCB_NOTIFY_DETAIL_ANCESTOR:
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ break;
+ case XCB_NOTIFY_DETAIL_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ break;
+ case XCB_NOTIFY_DETAIL_INFERIOR:
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ break;
+ case XCB_NOTIFY_DETAIL_POINTER:
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ break;
+ case XCB_NOTIFY_DETAIL_POINTER_ROOT:
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ break;
+ case XCB_NOTIFY_DETAIL_NONE:
+ e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+ break;
+ }
+ e->time = _ecore_xcb_event_last_time;
+ _ecore_xcb_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_focus_out(xcb_generic_event_t *event)
+{
+ xcb_focus_out_event_t *ev;
+ Ecore_X_Event_Window_Focus_Out *e;
+
+ ev = (xcb_focus_out_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
+ if (!e) return;
+ e->win = ev->event;
+ switch (ev->mode) {
+ case XCB_NOTIFY_MODE_NORMAL:
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ break;
+ case XCB_NOTIFY_MODE_GRAB:
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ break;
+ case XCB_NOTIFY_MODE_UNGRAB:
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+ break;
+ case XCB_NOTIFY_MODE_WHILE_GRABBED:
+ e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ break;
+ }
+ switch (ev->detail) {
+ case XCB_NOTIFY_DETAIL_ANCESTOR:
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ break;
+ case XCB_NOTIFY_DETAIL_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ break;
+ case XCB_NOTIFY_DETAIL_INFERIOR:
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ break;
+ case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ break;
+ case XCB_NOTIFY_DETAIL_POINTER:
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ break;
+ case XCB_NOTIFY_DETAIL_POINTER_ROOT:
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ break;
+ case XCB_NOTIFY_DETAIL_NONE:
+ e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+ break;
+ }
+ e->time = _ecore_xcb_event_last_time;
+ _ecore_xcb_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_keymap_notify(xcb_generic_event_t *event)
+{
+ /* FIXME: handle this event type */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_expose(xcb_generic_event_t *event)
+{
+ xcb_expose_event_t *ev;
+ Ecore_X_Event_Window_Damage *e;
+
+ ev = (xcb_expose_event_t *)event,
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e) return;
+ e->win = ev->window;
+ e->time = _ecore_xcb_event_last_time;
+ e->x = ev->x;
+ e->y = ev->y;
+ e->w = ev->width;
+ e->h = ev->height;
+ e->count = ev->count;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_graphics_expose(xcb_generic_event_t *event)
+{
+ xcb_graphics_exposure_event_t *ev;
+ Ecore_X_Event_Window_Damage *e;
+
+ ev = (xcb_graphics_exposure_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e) return;
+ e->win = ev->drawable;
+ e->time = _ecore_xcb_event_last_time;
+ e->x = ev->x;
+ e->y = ev->y;
+ e->w = ev->width;
+ e->h = ev->height;
+ e->count = ev->count;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_visibility_notify(xcb_generic_event_t *event)
+{
+ xcb_visibility_notify_event_t *ev;
+
+ ev = (xcb_visibility_notify_event_t *)event;
+ if (ev->state != XCB_VISIBILITY_PARTIALLY_OBSCURED)
+ {
+ Ecore_X_Event_Window_Visibility_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
+ if (!e) return;
+ e->win = ev->window;
+ e->time = _ecore_xcb_event_last_time;
+ if (ev->state == XCB_VISIBILITY_FULLY_OBSCURED)
+ e->fully_obscured = 1;
+ else
+ e->fully_obscured = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
+ }
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_create_notify(xcb_generic_event_t *event)
+{
+ xcb_create_notify_event_t *ev;
+ Ecore_X_Event_Window_Create *e;
+
+ ev = (xcb_create_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
+ if (!e) return;
+ e->win = ev->window;
+ if (ev->override_redirect)
+ e->override = 1;
+ else
+ e->override = 0;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_destroy_notify(xcb_generic_event_t *event)
+{
+ xcb_destroy_notify_event_t *ev;
+ Ecore_X_Event_Window_Destroy *e;
+
+ ev = (xcb_destroy_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
+ if (!e) return;
+ e->win = ev->window;
+ e->time = _ecore_xcb_event_last_time;
+ if (e->win == _ecore_xcb_event_last_window) _ecore_xcb_event_last_window = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_unmap_notify(xcb_generic_event_t *event)
+{
+ xcb_unmap_notify_event_t *ev;
+ Ecore_X_Event_Window_Hide *e;
+
+ ev = (xcb_unmap_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
+ if (!e) return;
+ e->win = ev->window;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_map_notify(xcb_generic_event_t *event)
+{
+ xcb_map_notify_event_t *ev;
+ Ecore_X_Event_Window_Show *e;
+
+ ev = (xcb_map_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
+ if (!e) return;
+ e->win = ev->window;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_map_request(xcb_generic_event_t *event)
+{
+ xcb_map_request_event_t *ev;
+ Ecore_X_Event_Window_Show_Request *e;
+
+ ev = (xcb_map_request_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
+ if (!e) return;
+ e->win = ev->window;
+ e->parent = ev->parent;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_reparent_notify(xcb_generic_event_t *event)
+{
+ xcb_reparent_notify_event_t *ev;
+ Ecore_X_Event_Window_Reparent *e;
+
+ ev = (xcb_reparent_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
+ if (!e) return;
+ e->win = ev->window;
+ e->parent = ev->parent;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_configure_notify(xcb_generic_event_t *event)
+{
+ xcb_configure_notify_event_t *ev;
+ Ecore_X_Event_Window_Configure *e;
+
+ ev = (xcb_configure_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
+ if (!e) return;
+ e->win = ev->window;
+ e->abovewin = ev->above_sibling;
+ e->x = ev->x;
+ e->y = ev->y;
+ e->w = ev->width;
+ e->h = ev->height;
+ e->border = ev->border_width;
+ e->override = ev->override_redirect;
+ /* send_event is bit 7 (0x80) of response_type */
+ e->from_wm = (ev->response_type & 0x80) ? 1 : 0;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_configure_request(xcb_generic_event_t *event)
+{
+ xcb_configure_request_event_t *ev;
+ Ecore_X_Event_Window_Configure_Request *e;
+
+ ev = (xcb_configure_request_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
+ if (!e) return;
+ e->win = ev->window;
+ e->abovewin = ev->sibling;
+ e->x = ev->x;
+ e->y = ev->y;
+ e->w = ev->width;
+ e->h = ev->height;
+ e->border = ev->border_width;
+ e->value_mask = ev->value_mask;
+ switch (ev->stack_mode) {
+ case XCB_STACK_MODE_ABOVE:
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ break;
+ case XCB_STACK_MODE_BELOW:
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ break;
+ case XCB_STACK_MODE_TOP_IF:
+ e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
+ break;
+ case XCB_STACK_MODE_BOTTOM_IF:
+ e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
+ break;
+ case XCB_STACK_MODE_OPPOSITE:
+ e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
+ break;
+ }
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_gravity_notify(xcb_generic_event_t *event)
+{
+ /* FIXME: handle this event type */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_resize_request(xcb_generic_event_t *event)
+{
+ xcb_resize_request_event_t *ev;
+ Ecore_X_Event_Window_Resize_Request *e;
+
+ ev = (xcb_resize_request_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
+ if (!e) return;
+ e->win = ev->window;
+ e->w = ev->width;
+ e->h = ev->height;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_circulate_notify(xcb_generic_event_t *event)
+{
+ xcb_circulate_notify_event_t *ev;
+ Ecore_X_Event_Window_Stack *e;
+
+ ev = (xcb_circulate_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
+ if (!e) return;
+ e->win = ev->window;
+ e->event_win = ev->event;
+ if (ev->place == XCB_PLACE_ON_TOP)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_circulate_request(xcb_generic_event_t *event)
+{
+ xcb_circulate_request_event_t *ev;
+ Ecore_X_Event_Window_Stack_Request *e;
+
+ ev = (xcb_circulate_request_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
+ if (!e) return;
+ e->win = ev->window;
+ e->parent = ev->event;
+ if (ev->place == XCB_PLACE_ON_TOP)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_property_notify(xcb_generic_event_t *event)
+{
+#if 0 /* for now i disabled this. nice idea though this is - it leaves a lot
+ * to be desired for efficiency that is better left to the app layer
+ */
+ if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS)
+ {
+ Ecore_X_Event_Window_Prop_Name_Class_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change));
+ if (!e) return;
+ ecore_x_window_prop_name_class_get(xevent->xproperty.window,
+ &(e->name), &(e->clas));
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e, _ecore_x_event_free_window_prop_name_class_change, NULL);
+ }
+ else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME))
+ {
+ Ecore_X_Event_Window_Prop_Title_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change));
+ if (!e) return;
+ e->title = ecore_x_window_prop_title_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_title_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME)
+ {
+ Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change));
+ if (!e) return;
+ e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_visible_title_change, NULL);
+ }
+ else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME))
+ {
+ Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_icon_name_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME)
+ {
+ Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_visible_icon_name_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
+ {
+ Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e, _ecore_x_event_free_window_prop_client_machine_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID)
+ {
+ Ecore_X_Event_Window_Prop_Pid_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change));
+ if (!e) return;
+ e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP)
+ {
+ Ecore_X_Event_Window_Prop_Desktop_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change));
+ if (!e) return;
+ e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window);
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
+ }
+ else
+#endif
+ {
+ xcb_property_notify_event_t *ev;
+ Ecore_X_Event_Window_Property *e;
+
+ ev = (xcb_property_notify_event_t *)event;
+ e = calloc(1,sizeof(Ecore_X_Event_Window_Property));
+ if (!e) return;
+ e->win = ev->window;
+ e->atom = ev->atom;
+ e->time = ev->time;
+ _ecore_xcb_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
+ }
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_selection_clear(xcb_generic_event_t *event)
+{
+ xcb_selection_clear_event_t *ev;
+ Ecore_X_Selection_Intern *d;
+ Ecore_X_Event_Selection_Clear *e;
+ Ecore_X_Atom sel;
+
+ ev = (xcb_selection_clear_event_t *)event;
+ d = _ecore_x_selection_get(ev->selection);
+ if (d && (ev->time > d->time))
+ {
+ _ecore_x_selection_set(XCB_NONE, NULL, 0,
+ ev->selection);
+ }
+
+ /* Generate event for app cleanup */
+ e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
+ e->win = ev->owner;
+ e->time = ev->time;
+ e->atom = sel = ev->selection;
+ if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+ ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_selection_request(xcb_generic_event_t *event)
+{
+ xcb_selection_request_event_t *ev;
+ Ecore_X_Selection_Intern *sd;
+ xcb_selection_notify_event_t sn_event;
+ void *data;
+
+ ev = (xcb_selection_request_event_t *)event;
+ /* FIXME: is it the correct value ? */
+ sn_event.response_type = XCB_SELECTION_NOTIFY;
+ sn_event.pad0 = 0;
+ /* FIXME: is it the correct value ? */
+ sn_event.sequence = 0;
+ sn_event.time = XCB_CURRENT_TIME;
+ sn_event.requestor = ev->requestor;
+ sn_event.selection = ev->selection;
+ sn_event.target = ev->target;
+
+ if ((sd = _ecore_x_selection_get(ev->selection)) &&
+ (sd->win == ev->owner))
+ {
+ if (!ecore_x_selection_convert(ev->selection, ev->target,
+ &data))
+ {
+ /* Refuse selection, conversion to requested target failed */
+ sn_event.property = XCB_NONE;
+ }
+ else
+ {
+ /* FIXME: This does not properly handle large data transfers */
+ ecore_x_window_prop_property_set(ev->requestor,
+ ev->property,
+ ev->target,
+ 8, data, sd->length);
+ sn_event.property = ev->property;
+ free(data);
+ }
+ }
+ else
+ {
+ sn_event.property = XCB_NONE;
+ return;
+ }
+
+ /* FIXME: I use _ecore_xcb_conn, as ev has no information on the connection */
+ xcb_send_event(_ecore_xcb_conn, 0,
+ ev->requestor, 0, (const char *)&sn_event);
+
+ free(event);
+}
+
+/* FIXME: round trip */
+void
+_ecore_x_event_handle_selection_notify(xcb_generic_event_t *event)
+{
+ xcb_selection_notify_event_t *ev;
+ Ecore_X_Event_Selection_Notify *e;
+ unsigned char *data = NULL;
+ Ecore_X_Atom selection;
+ int num_ret;
+ uint8_t format;
+
+ ev = (xcb_selection_notify_event_t *)event;
+ selection = ev->selection;
+
+ if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS)
+ {
+ ecore_x_window_prop_property_get_prefetch(ev->requestor,
+ ev->property,
+ ECORE_X_ATOM_ATOM);
+ ecore_x_window_prop_property_get_fetch();
+ format = ecore_x_window_prop_property_get(ev->requestor,
+ ev->property,
+ ECORE_X_ATOM_ATOM,
+ 32,
+ &data,
+ &num_ret);
+ if (!format) return;
+ }
+ else
+ {
+ ecore_x_window_prop_property_get_prefetch(ev->requestor,
+ ev->property,
+ XCB_GET_PROPERTY_TYPE_ANY);
+ ecore_x_window_prop_property_get_fetch();
+ format = ecore_x_window_prop_property_get(ev->requestor,
+ ev->property,
+ ECORE_X_ATOM_ATOM,
+ 8,
+ &data,
+ &num_ret);
+ if (!format) return;
+ }
+
+ e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
+ if (!e) return;
+ e->win = ev->requestor;
+ e->time = ev->time;
+ e->atom = selection;
+ e->target = _ecore_x_selection_target_get(ev->target);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ e->selection = ECORE_X_SELECTION_XDND;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+
+ e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
+
+ ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_colormap_notify(xcb_generic_event_t *event)
+{
+ xcb_colormap_notify_event_t *ev;
+ Ecore_X_Event_Window_Colormap *e;
+
+ ev = (xcb_colormap_notify_event_t *)event;
+ e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap));
+ if (!e) return;
+ e->win = ev->window;
+ e->cmap = ev->colormap;
+ if (ev->state == XCB_COLORMAP_STATE_INSTALLED)
+ e->installed = 1;
+ else
+ e->installed = 0;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_client_message(xcb_generic_event_t *event)
+{
+ /* Special client message event handling here. need to put LOTS of if */
+ /* checks here and generate synthetic events per special message known */
+ /* otherwise generate generic client message event. this would handle*/
+ /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
+
+ xcb_client_message_event_t *ev;
+
+ ev = (xcb_client_message_event_t *)event;
+ if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) &&
+ (ev->format == 32) &&
+ (ev->data.data32[0] == (uint32_t)ECORE_X_ATOM_WM_DELETE_WINDOW))
+ {
+ Ecore_X_Event_Window_Delete_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
+ if (!e) return;
+ e->win = ev->window;
+ e->time = _ecore_xcb_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
+ }
+
+ else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
+ (ev->format == 32) &&
+ /* Ignore move and resize with keyboard */
+ (ev->data.data32[2] < 9))
+ {
+ Ecore_X_Event_Window_Move_Resize_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
+ if (!e) return;
+ e->win = ev->window;
+ e->x = ev->data.data32[0];
+ e->y = ev->data.data32[1];
+ e->direction = ev->data.data32[2];
+ e->button = ev->data.data32[3];
+ e->source = ev->data.data32[4];
+ ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
+ }
+
+ /* Xdnd Client Message Handling Begin */
+ /* Message Type: XdndEnter target */
+ else if (ev->type == ECORE_X_ATOM_XDND_ENTER)
+ {
+ Ecore_X_Event_Xdnd_Enter *e;
+ Ecore_X_DND_Target *target;
+ uint32_t three;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
+ if (!e) return;
+
+ target = _ecore_x_dnd_target_get();
+ target->state = ECORE_X_DND_TARGET_ENTERED;
+
+ target = _ecore_x_dnd_target_get();
+ target->source = ev->data.data32[0];
+ target->win = ev->window;
+ target->version = ev->data.data32[1] >> 24;
+ if (target->version > ECORE_X_DND_VERSION)
+ {
+ WRN("DND: Requested version %d, we only support up to %d", target->version,
+ ECORE_X_DND_VERSION);
+ return;
+ }
+
+ /* FIXME: roud trip, but I don't know how to suppress it */
+ if ((three = ev->data.data32[1] & 0x1UL))
+ {
+ /* source supports more than 3 types, fetch property */
+ unsigned char *data;
+ Ecore_X_Atom *types;
+ int num_ret;
+ int i;
+ uint8_t format;
+
+ ecore_x_window_prop_property_get_prefetch(target->source,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM);
+ ecore_x_window_prop_property_get_fetch();
+ format = ecore_x_window_prop_property_get(target->source,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ ECORE_X_ATOM_ATOM,
+ 32,
+ &data,
+ &num_ret);
+ if (!format)
+ {
+ ERR("DND: Could not fetch data type list from source window, aborting.");
+ return;
+ }
+ types = (Ecore_X_Atom *)data;
+ e->types = calloc(num_ret, sizeof(char *));
+ if (e->types)
+ {
+ xcb_get_atom_name_cookie_t *cookies;
+
+ cookies = (xcb_get_atom_name_cookie_t *)malloc(sizeof(xcb_get_atom_name_cookie_t) * num_ret);
+ for (i = 0; i < num_ret; i++)
+ cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, types[i]);
+ for (i = 0; i < num_ret; i++)
+ {
+ xcb_get_atom_name_reply_t *reply;
+ char *name;
+
+ reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
+ if (reply)
+ {
+ name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
+ memcpy(name,
+ xcb_get_atom_name_name(reply),
+ reply->name_len);
+ name[reply->name_len] = '\0';
+ e->types[i] = name;
+ free(reply);
+ }
+ }
+ free(cookies);
+ }
+ e->num_types = num_ret;
+ }
+ else
+ {
+ int i = 0;
+
+ e->types = calloc(3, sizeof(char *));
+ if (e->types)
+ {
+ xcb_get_atom_name_cookie_t cookies[3];
+
+ for (i = 0; i < 3; i++)
+ cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[i + 2]);
+ for (i = 0; i < 3; i++)
+ {
+ xcb_get_atom_name_reply_t *reply;
+ char *name;
+
+ reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
+ if (reply && (ev->data.data32[i + 2]))
+ {
+ name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
+ memcpy(name,
+ xcb_get_atom_name_name(reply),
+ reply->name_len);
+ name[reply->name_len] = '\0';
+ e->types[i] = name;
+ }
+ if (reply) free(reply);
+ }
+ }
+ e->num_types = i;
+ }
+
+ e->win = target->win;
+ e->source = target->source;
+ ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL);
+ }
+
+ /* Message Type: XdndPosition target */
+ else if (ev->type == ECORE_X_ATOM_XDND_POSITION)
+ {
+ Ecore_X_Event_Xdnd_Position *e;
+ Ecore_X_DND_Target *target;
+
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
+ (target->win != ev->window))
+ return;
+
+ target->pos.x = (int16_t)ev->data.data32[2] >> 16;
+ target->pos.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
+ target->action = ev->data.data32[4]; /* Version 2 */
+
+ target->time = (target->version >= 1) ?
+ ev->data.data32[3] : XCB_CURRENT_TIME;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ e->action = target->action;
+ ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndStatus source */
+ else if (ev->type == ECORE_X_ATOM_XDND_STATUS)
+ {
+ Ecore_X_Event_Xdnd_Status *e;
+ Ecore_X_DND_Source *source;
+
+ source = _ecore_x_dnd_source_get();
+ /* Make sure source/target match */
+ if ((source->win != ev->window ) ||
+ (source->dest != ev->data.data32[0]))
+ return;
+
+ source->await_status = 0;
+
+ source->will_accept = ev->data.data32[1] & 0x1UL;
+ source->suppress = (ev->data.data32[1] & 0x2UL) ? 0 : 1;
+
+ source->rectangle.x = (int16_t)ev->data.data32[2] >> 16;
+ source->rectangle.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
+ source->rectangle.width = (uint16_t)ev->data.data32[3] >> 16;
+ source->rectangle.height = (uint16_t)ev->data.data32[3] & 0xFFFFUL;
+
+ source->accepted_action = ev->data.data32[4];
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
+ if (!e) return;
+ e->win = source->win;
+ e->target = source->dest;
+ e->will_accept = source->will_accept;
+ e->rectangle.x = source->rectangle.x;
+ e->rectangle.y = source->rectangle.y;
+ e->rectangle.width = source->rectangle.width;
+ e->rectangle.height = source->rectangle.height;
+ e->action = source->accepted_action;
+
+ ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndLeave target */
+ /* Pretend the whole thing never happened, sort of */
+ else if (ev->type == ECORE_X_ATOM_XDND_LEAVE)
+ {
+ Ecore_X_Event_Xdnd_Leave *e;
+ Ecore_X_DND_Target *target;
+
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
+ (target->win != ev->window))
+ return;
+
+ target->state = ECORE_X_DND_TARGET_IDLE;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
+ if (!e) return;
+ e->win = ev->window;
+ e->source = ev->data.data32[0];
+ ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndDrop target */
+ else if (ev->type == ECORE_X_ATOM_XDND_DROP)
+ {
+ Ecore_X_Event_Xdnd_Drop *e;
+ Ecore_X_DND_Target *target;
+
+ target = _ecore_x_dnd_target_get();
+ /* Match source/target */
+ if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
+ (target->win != ev->window))
+ return;
+
+ target->time = (target->version >= 1) ?
+ ev->data.data32[2] : _ecore_xcb_event_last_time;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->action = target->action;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndFinished source */
+ else if (ev->type == ECORE_X_ATOM_XDND_FINISHED)
+ {
+ Ecore_X_Event_Xdnd_Finished *e;
+ Ecore_X_DND_Source *source;
+ uint8_t completed = 1;
+
+ source = _ecore_x_dnd_source_get();
+ /* Match source/target */
+ if ((source->win != ev->window) ||
+ (source->dest != ev->data.data32[0]))
+ return;
+
+ if ((source->version >= 5) && (ev->data.data32[1] & 0x1UL))
+ {
+ /* Target successfully performed drop action */
+ ecore_x_selection_xdnd_clear();
+ source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ else
+ {
+ completed = 0;
+ source->state = ECORE_X_DND_SOURCE_CONVERTING;
+
+ /* FIXME: Probably need to add a timer to switch back to idle
+ * and discard the selection data */
+ }
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
+ if (!e) return;
+ e->win = source->win;
+ e->target = source->dest;
+ e->completed = completed;
+ if (source->version >= 5)
+ {
+ source->accepted_action = ev->data.data32[2];
+ e->action = source->accepted_action;
+ }
+ else
+ {
+ source->accepted_action = 0;
+ e->action = source->action;
+ }
+
+ ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
+ }
+ else if (ev->type == ECORE_X_ATOM_NET_WM_STATE)
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
+ if (!e) return;
+ e->win = ev->window;
+ if (ev->data.data32[0] == 0)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
+ else if (ev->data.data32[0] == 1)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ else if (ev->data.data32[0] == 2)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
+ else
+ {
+ free(e);
+ return;
+ }
+ e->state[0] = _ecore_x_netwm_state_get(ev->data.data32[1]);
+ if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+ xcb_get_atom_name_reply_t *reply;
+ char *name;
+
+ /* FIXME: round trip */
+ reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
+ xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[1]),
+ NULL);
+ if (reply)
+ {
+ name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
+ memcpy(name,
+ xcb_get_atom_name_name(reply),
+ reply->name_len);
+ name[reply->name_len] = '\0';
+ ERR("Unknown state: %s", name);
+ free(name);
+ free(reply);
+ }
+ }
+ e->state[1] = _ecore_x_netwm_state_get(ev->data.data32[2]);
+ if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+ xcb_get_atom_name_reply_t *reply;
+ char *name;
+
+ reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
+ xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[2]),
+ NULL);
+ if (reply)
+ {
+ name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
+ memcpy(name,
+ xcb_get_atom_name_name(reply),
+ reply->name_len);
+ name[reply->name_len] = '\0';
+ WRN("Unknown state: %s", name);
+ free(name);
+ }
+ }
+ e->source = ev->data.data32[3];
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+ else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE)
+ && (ev->format == 32)
+ && (ev->data.data32[0] == XCB_WM_HINT_STATE))
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
+ if (!e) return;
+ e->win = ev->window;
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+ else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP)
+ && (ev->format == 32))
+ {
+ Ecore_X_Event_Desktop_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
+ if (!e) return;
+ e->win = ev->window;
+ e->desk = ev->data.data32[0];
+ e->source = ev->data.data32[1];
+
+ ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
+ }
+ else if ((ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
+ {
+ Ecore_X_Event_Frame_Extents_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
+ if (!e) return;
+ e->win = ev->window;
+
+ ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
+ }
+ else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS)
+ && ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING)
+ && (ev->format == 32))
+ {
+ Ecore_X_Event_Ping *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Ping));
+ if (!e) return;
+ e->win = ev->window;
+ e->time = ev->data.data32[1];
+ e->event_win = ev->data.data32[2];
+
+ ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
+ }
+ else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
+ (ev->format == 8))
+ {
+ _ecore_x_netwm_startup_info_begin(ev->window, (char *)ev->data.data8);
+ }
+ else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
+ (ev->format == 8))
+ {
+ _ecore_x_netwm_startup_info(ev->window, (char *)ev->data.data8);
+ }
+ else if ((ev->type == 27777)
+ && (ev->data.data32[0] == 0x7162534)
+ && (ev->format == 32)
+ && (ev->window == _ecore_xcb_private_window))
+ {
+ /* a grab sync marker */
+ if (ev->data.data32[1] == 0x10000001)
+ _ecore_x_window_grab_remove(ev->data.data32[2]);
+ else if (ev->data.data32[1] == 0x10000002)
+ _ecore_x_key_grab_remove(ev->data.data32[2]);
+ }
+ else
+ {
+ Ecore_X_Event_Client_Message *e;
+ int i;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
+ if (!e) return;
+ e->win = ev->window;
+ e->message_type = ev->type;
+ e->format = ev->format;
+ for (i = 0; i < 5; i++)
+ e->data.l[i] = ev->data.data32[i];
+
+ ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
+ }
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_mapping_notify(xcb_generic_event_t *event)
+{
+ /* FIXME: handle this event type */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_shape_change(xcb_generic_event_t *event)
+{
+#ifdef ECORE_X_SHAPE
+ xcb_shape_notify_event_t *ev;
+ Ecore_X_Event_Window_Shape *e;
+
+ ev = (xcb_shape_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
+ if (!e) return;
+ e->win = ev->affected_window;
+ e->time = ev->server_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
+#endif /* ECORE_X_SHAPE */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_screensaver_notify(xcb_generic_event_t *event)
+{
+#ifdef ECORE_X_SCREENSAVER
+ xcb_screensaver_notify_event_t *ev;
+ Ecore_X_Event_Screensaver_Notify *e;
+
+ ev = (xcb_screensaver_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
+ if (!e) return;
+ e->win = ev->window;
+ if (ev->state == XCB_SCREENSAVER_STATE_ON)
+ e->on = 1;
+ else
+ e->on = 0;
+ e->time = ev->time;
+ ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
+#endif /* ECORE_X_SCREENSAVER */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_sync_counter(xcb_generic_event_t *event)
+{
+#ifdef ECORE_X_SYNC
+ xcb_sync_counter_notify_event_t *ev;
+ Ecore_X_Event_Sync_Counter *e;
+
+ ev = (xcb_sync_counter_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
+ if (!e) return;
+ e->time = ev->timestamp;
+ ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
+#endif /* ECORE_X_SYNC */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_sync_alarm(xcb_generic_event_t *event)
+{
+#ifdef ECORE_X_SYNC
+ xcb_sync_alarm_notify_event_t *ev;
+ Ecore_X_Event_Sync_Alarm *e;
+
+ ev = (xcb_sync_alarm_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
+ if (!e) return;
+ e->time = ev->timestamp;
+ e->alarm = ev->alarm;
+ ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
+#endif /* ECORE_X_SYNC */
+
+ free(event);
+}
+
+/* FIXME: round trip */
+void
+_ecore_x_event_handle_randr_change(xcb_generic_event_t *event)
+{
+#ifdef ECORE_X_RANDR
+ xcb_randr_screen_change_notify_event_t *ev;
+ Ecore_X_Event_Screen_Change *e;
+
+ ev = (xcb_randr_screen_change_notify_event_t *)event;
+
+ if ((ev->response_type & ~0x80) != XCB_CONFIGURE_NOTIFY)
+ {
+ xcb_query_extension_reply_t *rep;
+
+ rep = xcb_query_extension_reply(_ecore_xcb_conn,
+ xcb_query_extension_unchecked(_ecore_xcb_conn,
+ strlen("randr"),
+ "randr"),
+ NULL);
+
+ if ((!rep) ||
+ (((ev->response_type & ~0x80) - rep->first_event) != XCB_RANDR_SCREEN_CHANGE_NOTIFY))
+ WRN("ERROR: Can't update RandR config!");
+ if (rep)
+ free(rep);
+ }
+
+ e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
+ if (!e) return;
+ e->win = ev->request_window;
+ e->root = ev->root;
+ e->width = ev->width;
+ e->height = ev->height;
+ ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
+#endif /* ECORE_X_RANDR */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_fixes_selection_notify(xcb_generic_event_t *event)
+{
+#ifdef ECORE_X_FIXES
+ /* Nothing here yet */
+#endif /* ECORE_X_FIXES */
+
+ free(event);
+}
+
+void
+_ecore_x_event_handle_damage_notify(xcb_generic_event_t *event)
+{
+#ifdef ECORE_XCBDAMAGE
+ xcb_damage_notify_event_t *ev;
+ Ecore_X_Event_Damage *e;
+
+ ev = (xcb_damage_notify_event_t *)event;
+ e = calloc(1, sizeof(Ecore_X_Event_Damage));
+ if (!e) return;
+
+ e->level = ev->level;
+ e->drawable = ev->drawable;
+ e->damage = ev->damage;
+ /* FIXME: XCB has no 'more' member in xcb_damage_notify_event_t */
+/* e->more = ev->more; */
+ e->time = ev->timestamp;
+ e->area.x = ev->area.x;
+ e->area.y = ev->area.y;
+ e->area.width = ev->area.width;
+ e->area.height = ev->area.height;
+ e->geometry.x = ev->geometry.x;
+ e->geometry.y = ev->geometry.y;
+ e->geometry.width = ev->geometry.width;
+ e->geometry.height = ev->geometry.height;
+
+ ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
+#endif /* ECORE_XCBDAMAGE */
+
+ free(event);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Fixes_Group X Fixes Extension Functions
+ *
+ * Functions related to the X Fixes extension.
+ */
+
+
+#ifdef ECORE_XCB_FIXES
+static int _xfixes_available = 0;
+static xcb_xfixes_query_version_cookie_t _ecore_xcb_xfixes_init_cookie;
+#endif /* ECORE_XCB_FIXES */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_xfixes_init and
+ _ecore_xcb_xfixes_init_finalize. The first one gets the cookies and
+ the second one gets the replies and set the atoms. */
+
+void
+_ecore_x_xfixes_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_FIXES
+ if (reply && (reply->present))
+ _ecore_xcb_xfixes_init_cookie = xcb_xfixes_query_version_unchecked(_ecore_xcb_conn, 4, 0);
+#endif /* ECORE_XCB_FIXES */
+}
+
+void
+_ecore_x_xfixes_init_finalize(void)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_query_version_reply_t *reply;
+
+ reply = xcb_xfixes_query_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_xfixes_init_cookie, NULL);
+
+ if (reply)
+ {
+ if (reply->major_version >= 3)
+ _xfixes_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Return whether the X server supports the Fixes Extension.
+ * @return 1 if the X Fixes Extension is available, 0 otherwise.
+ *
+ * Return 1 if the X server supports the Fixes Extension version 3.0,
+ * 0 otherwise.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI int
+ecore_x_xfixes_query(void)
+{
+#ifdef ECORE_XCB_FIXES
+ return _xfixes_available;
+#else
+ return 0;
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Create a region from rectangles.
+ * @param rects The rectangles used to initialize the region.
+ * @param num The number of rectangles.
+ * @return The newly created region.
+ *
+ * Create a region initialized to the specified list of rectangles
+ * @p rects. The rectangles may be specified in any order, their union
+ * becomes the region.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI Ecore_X_Region
+ecore_x_region_new(Ecore_X_Rectangle *rects,
+ int num)
+{
+ Ecore_X_Region region = XCB_NONE;
+
+#ifdef ECORE_XCB_FIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region(_ecore_xcb_conn, region, num, (xcb_rectangle_t *)rects);
+#endif /* ECORE_XCB_FIXES */
+
+ return region;
+}
+
+
+/**
+ * Create a region from a pixmap.
+ * @param bitmap The bitmap used to initialize the region.
+ * @return The newly created region.
+ *
+ * Creates a region initialized to the set of 'one' pixels in @p bitmap
+ * (which must be of depth 1, else Match error).
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI Ecore_X_Region
+ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap)
+{
+ Ecore_X_Region region = XCB_NONE;
+
+#ifdef ECORE_XCB_FIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_bitmap(_ecore_xcb_conn, region, bitmap);
+#endif /* ECORE_XCB_FIXES */
+
+ return region;
+}
+
+
+/**
+ * Create a region from a window.
+ * @param window The window used to initialize the region.
+ * @param type The type of the region.
+ * @return The newly created region.
+ *
+ * Creates a region initialized to the specified @p window region. See
+ * the Shape extension for the definition of Bounding and Clip
+ * regions.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI Ecore_X_Region
+ecore_x_region_new_from_window(Ecore_X_Window window,
+ Ecore_X_Region_Type type)
+{
+ Ecore_X_Region region = XCB_NONE;
+
+#ifdef ECORE_XCB_FIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_window(_ecore_xcb_conn, region, window, type);
+#endif /* ECORE_XCB_FIXES */
+
+ return region;
+}
+
+
+/**
+ * Create a region from a graphic context.
+ * @param gc The graphic context used to initialize the region.
+ * @return The newly created region.
+ *
+ * Creates a region initialized from the clip list of @p gc.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI Ecore_X_Region
+ecore_x_region_new_from_gc(Ecore_X_GC gc)
+{
+ Ecore_X_Region region = XCB_NONE;
+
+#ifdef ECORE_XCB_FIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_gc(_ecore_xcb_conn, region, gc);
+#endif /* ECORE_XCB_FIXES */
+
+ return region;
+}
+
+
+/**
+ * Create a region from a picture.
+ * @param picture The picture used to initialize the region.
+ * @return The newly created region.
+ *
+ * Creates a region initialized from the clip list of @p picture.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI Ecore_X_Region
+ecore_x_region_new_from_picture(Ecore_X_Picture picture)
+{
+ Ecore_X_Region region = XCB_NONE;
+
+#ifdef ECORE_XCB_FIXES
+ region = xcb_generate_id(_ecore_xcb_conn);
+ xcb_xfixes_create_region_from_picture(_ecore_xcb_conn, region, picture);
+#endif /* ECORE_XCB_FIXES */
+
+ return region;
+}
+
+
+/**
+ * Destroy a region.
+ * @param region The region to destroy.
+ *
+ * Destroy the specified @p region.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_free(Ecore_X_Region region)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_destroy_region(_ecore_xcb_conn, region);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Set the content of a region.
+ * @param region The region to destroy.
+ * @param rects The rectangles used to set the region.
+ * @param num The number of rectangles.
+ *
+ * Replace the current contents of @p region with the region formed
+ * by the union of the rectangles @p rects.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_set(Ecore_X_Region region,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_set_region(_ecore_xcb_conn, region, num, (xcb_rectangle_t *)rects);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Copy the content of a region.
+ * @param dest The destination region.
+ * @param source The source region.
+ *
+ * Replace the contents of @p dest with the contents of @p source.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_copy(Ecore_X_Region dest,
+ Ecore_X_Region source)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_copy_region(_ecore_xcb_conn, source, dest);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Make the union of two regions.
+ * @param dest The destination region.
+ * @param source1 The first source region.
+ * @param source2 The second source region.
+ *
+ * Replace the contents of @p dest with the union of @p source1 and
+ * @p source2.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_combine(Ecore_X_Region dest,
+ Ecore_X_Region source1,
+ Ecore_X_Region source2)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Make the intersection of two regions.
+ * @param dest The destination region.
+ * @param source1 The first source region.
+ * @param source2 The second source region.
+ *
+ * Replace the contents of @p dest with the intersection of @p source1 and
+ * @p source2.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_intersect(Ecore_X_Region dest,
+ Ecore_X_Region source1,
+ Ecore_X_Region source2)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Make the substraction of two regions.
+ * @param dest The destination region.
+ * @param source1 The first source region.
+ * @param source2 The second source region.
+ *
+ * Replace the contents of @p dest with the substraction of @p source1 by
+ * @p source2.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_subtract(Ecore_X_Region dest,
+ Ecore_X_Region source1,
+ Ecore_X_Region source2)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Make the substraction of regions by bounds.
+ * @param dest The destination region.
+ * @param bounds The bounds.
+ * @param source The source region.
+ *
+ * The @p source region is subtracted from the region specified by
+ * @p bounds. The result is placed in @p dest, replacing its
+ * contents.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_invert(Ecore_X_Region dest,
+ Ecore_X_Rectangle *bounds,
+ Ecore_X_Region source)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_rectangle_t rect;
+
+ rect.x = bounds->x;
+ rect.y = bounds->y;
+ rect.width = bounds->width;
+ rect.height = bounds->height;
+ xcb_xfixes_invert_region(_ecore_xcb_conn, source, rect, dest);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Translate a region.
+ * @param region The region to translate.
+ * @param dx The horizontal translation.
+ * @param dy The vertical translation.
+ *
+ * The @p region is translated by @p dx and @p dy in place.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_translate(Ecore_X_Region region,
+ int dx,
+ int dy)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Extent a region.
+ * @param dest The destination region.
+ * @param source The source region.
+ *
+ * The extents of the @p source region are placed in @p dest.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_extents(Ecore_X_Region dest,
+ Ecore_X_Region source)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Sends the XFixesFetchRegion request.
+ * @param region Requested region.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_fetch_prefetch(Ecore_X_Region region)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_fetch_region_cookie_t cookie;
+
+ cookie = xcb_xfixes_fetch_region_unchecked(_ecore_xcb_conn, region);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Gets the reply of the XFixesFetchRegion request sent by ecore_xcb_region_fetch_prefetch().
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_fetch_fetch(void)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_fetch_region_cookie_t cookie;
+ xcb_xfixes_fetch_region_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_xfixes_fetch_region_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Return the rectangles that compose a region.
+ * @param region The region (Unused).
+ * @param num The number of returned rectangles.
+ * @param bounds The returned bounds of the region.
+ * @return The returned rectangles.
+ *
+ * The @p region passed to ecore_xcb_region_fetch_prefetch() is
+ * returned as a list of rectagles in XY-banded order.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_xcb_region_fetch_prefetch(), which sends the XFixesFetchRegion request,
+ * then ecore_xcb_region_fetch_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI Ecore_X_Rectangle *
+ecore_x_region_fetch(Ecore_X_Region region __UNUSED__,
+ int *num,
+ Ecore_X_Rectangle *bounds)
+{
+ Ecore_X_Rectangle extents = { 0, 0, 0, 0};
+ Ecore_X_Rectangle *rects = NULL;
+#ifdef ECORE_XCB_FIXES
+ int n;
+ xcb_xfixes_fetch_region_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ {
+ if (num) *num = 0;
+ if (bounds) *bounds = extents;
+ return NULL;
+ }
+ n = xcb_xfixes_fetch_region_rectangles_length(reply);
+ rects = (Ecore_X_Rectangle *)malloc(n * sizeof(Ecore_X_Rectangle));
+ if (!rects)
+ {
+ if (num) *num = 0;
+ if (bounds) *bounds = extents;
+
+ return NULL;
+ }
+
+ if (num) *num = n;
+ if (bounds)
+ {
+ bounds->x = reply->extents.x;
+ bounds->y = reply->extents.y;
+ bounds->width = reply->extents.width;
+ bounds->height = reply->extents.height;
+ }
+ memcpy(rects,
+ xcb_xfixes_fetch_region_rectangles(reply),
+ sizeof(Ecore_X_Rectangle) * n);
+
+ return rects;
+#else
+ if (num) *num = 0;
+ if (bounds) *bounds = extents;
+ return NULL;
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Expand a region.
+ * @param dest The destination region.
+ * @param source The source region.
+ * @param left The number of pixels to add on the left.
+ * @param right The number of pixels to add on the right.
+ * @param top The number of pixels to add at the top.
+ * @param bottom The number of pixels to add at the bottom.
+ *
+ * Put in @p dest the area specified by expanding each rectangle in
+ * the @p source region by the specified number of pixels to the
+ * @p left, @p right, @p top and @p bottom.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_expand(Ecore_X_Region dest,
+ Ecore_X_Region source,
+ unsigned int left,
+ unsigned int right,
+ unsigned int top,
+ unsigned int bottom)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Change clip-mask in a graphic context to the specified region.
+ * @param region The region to change.
+ * @param gc The clip-mask graphic context.
+ * @param x_origin The horizontal translation.
+ * @param y_origin The vertical translation.
+ *
+ * Changes clip-mask in @p gc to the specified @p region and
+ * sets the clip origin with the values of @p x_origin and @p y_origin.
+ * Output will be clippped to remain contained within the region. The
+ * clip origin is interpreted relative to the origin of whatever
+ * destination drawable is specified in a graphics request. The
+ * region is interpreted relative to the clip origin. Future changes
+ * to region have no effect on the gc clip-mask.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_gc_clip_set(Ecore_X_Region region,
+ Ecore_X_GC gc,
+ int x_origin,
+ int y_origin)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x_origin, y_origin);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Change the shape extension of a window.
+ * @param region The region.
+ * @param dest The window whose shape is changed.
+ * @param type The kind of shape.
+ * @param x_offset The horizontal offset.
+ * @param y_offset The vertical offset.
+ *
+ * Set the specified Shape extension region of @p window to @p region,
+ * offset by @p x_offset and @p y_offset. Future changes to region
+ * have no effect on the window shape.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_window_shape_set(Ecore_X_Region region,
+ Ecore_X_Window dest,
+ Ecore_X_Shape_Type type,
+ int x_offset,
+ int y_offset)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x_offset, y_offset, region);
+#endif /* ECORE_XCB_FIXES */
+}
+
+
+/**
+ * Change clip-mask in picture to the specified region.
+ * @param region The region.
+ * @param picture The picture.
+ * @param x_origin The X coordinate of the origin.
+ * @param y_origin The Y coordinate of the origin.
+ *
+ * Changes clip-mask in picture to the specified @p region
+ * and sets the clip origin. Input and output will be clipped to
+ * remain contained within the region. The clip origin is interpreted
+ * relative to the origin of the drawable associated with @p picture. The
+ * region is interpreted relative to the clip origin. Future changes
+ * to region have no effect on the picture clip-mask.
+ * @ingroup Ecore_X_Fixes_Group
+ */
+EAPI void
+ecore_x_region_picture_clip_set(Ecore_X_Region region,
+ Ecore_X_Picture picture,
+ int x_origin,
+ int y_origin)
+{
+#ifdef ECORE_XCB_FIXES
+ xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x_origin, y_origin);
+#endif /* ECORE_XCB_FIXES */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * Creates a new default graphics context associated with the given
+ * drawable.
+ * @param drawable Drawable to create graphics context with. If @c 0 is
+ * given instead, the default root window is used.
+ * @param value_mask Bitmask values.
+ * @param value_list List of values. The order of values must be the
+ * same than the corresponding bitmaks.
+ * @return The new default graphics context.
+ *
+ * Creates a new default graphics context associated with @p
+ * drawable. The graphic context can be used with any destination
+ * drawable having the same root and depth as @p drawable. Use with
+ * other drawables results in a BadMatch error.
+ */
+EAPI Ecore_X_GC
+ecore_x_gc_new(Ecore_X_Drawable drawable, Ecore_X_GC_Value_Mask value_mask, const unsigned int *value_list)
+{
+ xcb_gcontext_t gc;
+
+ if (!drawable) drawable = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ gc = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_gc(_ecore_xcb_conn, gc, drawable, value_mask, value_list);
+
+ return gc;
+}
+
+
+/**
+ * Deletes and frees the given graphics context.
+ * @param gc The given graphics context.
+ *
+ * Destroyes the graphic context @p gc as well as the associated
+ * storage.
+ */
+EAPI void
+ecore_x_gc_free(Ecore_X_GC gc)
+{
+ xcb_free_gc(_ecore_xcb_conn, gc);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * Various ICCCM related functions.
+ *
+ * This is ALL the code involving anything ICCCM related, for both WM and
+ * client.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <xcb/xcb_icccm.h>
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+/**
+ * @defgroup Ecore_X_ICCCM_Group ICCCM related functions.
+ *
+ * Functions related to ICCCM.
+ */
+
+
+static int _ecore_x_icccm_size_hints_get (const void *reply,
+ Ecore_X_Atom property,
+ xcb_size_hints_t *hints)
+{
+ uint32_t s;
+
+ if (!hints) return 0;
+
+ if (!reply) return 0;
+ if ((((xcb_get_property_reply_t *)reply)->type != ECORE_X_ATOM_WM_SIZE_HINTS) &&
+ ((((xcb_get_property_reply_t *)reply)->format != 8) ||
+ (((xcb_get_property_reply_t *)reply)->format != 16) ||
+ (((xcb_get_property_reply_t *)reply)->format != 32)) &&
+ (((xcb_get_property_reply_t *)reply)->value_len < 15)) /* OldNumPropSizeElements = 15 (pre-ICCCM) */
+ return 0;
+
+ memcpy(hints,
+ xcb_get_property_value((xcb_get_property_reply_t *)reply),
+ ((xcb_get_property_reply_t *)reply)->value_len);
+
+ s = (XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_US_SIZE |
+ XCB_SIZE_HINT_P_POSITION | XCB_SIZE_HINT_P_SIZE |
+ XCB_SIZE_HINT_P_MIN_SIZE | XCB_SIZE_HINT_P_MAX_SIZE |
+ XCB_SIZE_HINT_P_RESIZE_INC | XCB_SIZE_HINT_P_ASPECT);
+
+ if (((xcb_get_property_reply_t *)reply)->value_len >= 18) /* NumPropSizeElements = 18 (ICCCM version 1) */
+ s |= (XCB_SIZE_HINT_BASE_SIZE | XCB_SIZE_HINT_P_WIN_GRAVITY);
+ else
+ {
+ xcb_size_hints_set_base_size(hints, 0, 0);
+ xcb_size_hints_set_win_gravity(hints, 0);
+ }
+ /* FIXME: is it necessary ? */
+ /* hints->flags &= s; */ /* get rid of unwanted bits */
+
+ return 1;
+}
+
+
+/**
+ * Sets the state of a window.
+ * @param window The window.
+ * @param state The state.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_state_set(Ecore_X_Window window,
+ Ecore_X_Window_State_Hint state)
+{
+ uint32_t c[2];
+
+ if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ c[0] = XCB_WM_STATE_WITHDRAWN;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ c[0] = XCB_WM_STATE_NORMAL;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ c[0] = XCB_WM_STATE_ICONIC;
+ c[1] = 0;
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE, 32,
+ 2, c);
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_state_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_STATE,
+ ECORE_X_ATOM_WM_STATE,
+ 0L, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_state_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_state_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Gets the state of a window.
+ * @param window The window.
+ * @return The state of the window
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_state_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_state_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI Ecore_X_Window_State_Hint
+ecore_x_icccm_state_get(Ecore_X_Window window __UNUSED__)
+{
+ xcb_get_property_reply_t *reply;
+ uint8_t *prop;
+ Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return hint;
+
+ if ((reply->type == 0) ||
+ (reply->format != 8) ||
+ (reply->value_len != 2))
+ return hint;
+
+ prop = (uint8_t *)xcb_get_property_value(reply);
+ switch (prop[0]) {
+ case XCB_WM_STATE_WITHDRAWN:
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ break;
+ case XCB_WM_STATE_NORMAL:
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ break;
+ case XCB_WM_STATE_ICONIC:
+ hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ break;
+ default:
+ hint = ECORE_X_WINDOW_STATE_HINT_NONE;
+ break;
+ }
+
+ return hint;
+}
+
+/**
+ * Sends the ClientMessage event with the DeleteWindow property.
+ * @param window The window.
+ * @param time The time.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_delete_window_send(Ecore_X_Window window,
+ Ecore_X_Time time)
+{
+ ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_DELETE_WINDOW,
+ time, 0, 0, 0);
+}
+
+/**
+ * Sends the ClientMessage event with the TakeFocus property.
+ * @param window The window.
+ * @param time The time.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_take_focus_send(Ecore_X_Window window,
+ Ecore_X_Time time)
+{
+ ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_TAKE_FOCUS,
+ time, 0, 0, 0);
+}
+
+/**
+ * Sends the ClientMessage event with the SaveYourself property.
+ * @param window The window.
+ * @param time The time.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_save_yourself_send(Ecore_X_Window window,
+ Ecore_X_Time time)
+{
+ ecore_x_client_message32_send(window, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_SAVE_YOURSELF,
+ time, 0, 0, 0);
+}
+
+/**
+ * Sends the ConfigureNotify event with the StructureNotify property.
+ * @param window The window.
+ * @param x The X coordinate.
+ * @param y The Y coordinate.
+ * @param width The width.
+ * @param height The height.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_move_resize_send(Ecore_X_Window window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ xcb_configure_notify_event_t ev;
+
+ ev.response_type = XCB_CONFIGURE_NOTIFY | 0x80;
+ ev.pad0 = 0;
+ ev.sequence = 0;
+ ev.event = window;
+ ev.window = window;
+ ev.above_sibling = 0;
+ ev.x = x;
+ ev.y = y;
+ ev.width = width;
+ ev.height = height;
+ ev.border_width = 0;
+ ev.override_redirect = 0;
+ xcb_send_event(_ecore_xcb_conn, 0, window,
+ XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev);
+}
+
+/**
+ * Sets the hints of a window.
+ * @param window The window.
+ * @param accepts_focus AcceptFocus hint
+ * @param initial_state Initial state flags.
+ * @param icon_pixmap Icon pixmap.
+ * @param icon_mask Icon mask.
+ * @param icon_window Icon window.
+ * @param window_group Group window.
+ * @param is_urgent IsUrgent flag.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_hints_set(Ecore_X_Window window,
+ int accepts_focus,
+ Ecore_X_Window_State_Hint initial_state,
+ Ecore_X_Pixmap icon_pixmap,
+ Ecore_X_Pixmap icon_mask,
+ Ecore_X_Window icon_window,
+ Ecore_X_Window window_group,
+ int is_urgent)
+{
+ xcb_wm_hints_t hints;
+
+ memset(&hints, 0, sizeof(hints));
+ xcb_wm_hints_set_input(&hints, accepts_focus);
+ if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ xcb_wm_hints_set_withdrawn(&hints);
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ xcb_wm_hints_set_normal(&hints);
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ xcb_wm_hints_set_iconic(&hints);
+ if (icon_pixmap != 0)
+ xcb_wm_hints_set_icon_pixmap(&hints, icon_pixmap);
+ if (icon_mask != 0)
+ xcb_wm_hints_set_icon_mask(&hints, icon_mask);
+ if (icon_window != 0)
+ xcb_wm_hints_set_icon_window(&hints, icon_window);
+ if (window_group != 0)
+ xcb_wm_hints_set_window_group(&hints, window_group);
+ if (is_urgent)
+ xcb_wm_hints_set_urgency(&hints);
+ xcb_set_wm_hints(_ecore_xcb_conn, window, &hints);
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_hints_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_HINTS,
+ ECORE_X_ATOM_WM_HINTS,
+ 0L, XCB_NUM_WM_HINTS_ELEMENTS);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_hints_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_hints_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Gets the hints of a window.
+ * @param window The window.
+ * @param accepts_focus AcceptFocus hint
+ * @param initial_state Initial state flags.
+ * @param icon_pixmap Icon pixmap.
+ * @param icon_mask Icon mask.
+ * @param icon_window Icon window.
+ * @param window_group Group window.
+ * @param is_urgent IsUrgent flag.
+ * @return 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_hints_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_hints_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI int
+ecore_x_icccm_hints_get(Ecore_X_Window window __UNUSED__,
+ int *accepts_focus,
+ Ecore_X_Window_State_Hint *initial_state,
+ Ecore_X_Pixmap *icon_pixmap,
+ Ecore_X_Pixmap *icon_mask,
+ Ecore_X_Window *icon_window,
+ Ecore_X_Window *window_group,
+ int *is_urgent)
+{
+ xcb_wm_hints_t hints;
+ xcb_get_property_reply_t *reply;
+ uint32_t flags;
+
+ if (accepts_focus)
+ *accepts_focus = 1;
+ if (initial_state)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ if (icon_pixmap)
+ *icon_pixmap = 0;
+ if (icon_mask)
+ *icon_mask = 0;
+ if (icon_window)
+ *icon_window = 0;
+ if (window_group)
+ *window_group = 0;
+ if (is_urgent)
+ *is_urgent = 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ if ((reply->type != ECORE_X_ATOM_WM_HINTS) ||
+ (reply->value_len < (XCB_NUM_WM_HINTS_ELEMENTS - 1)) ||
+ (reply->format != 32))
+ return 0;
+
+ xcb_get_wm_hints_from_reply(&hints, reply);
+
+ flags = xcb_wm_hints_get_flags(&hints);
+ if ((flags & XCB_WM_HINT_INPUT) && (accepts_focus))
+ {
+ if (xcb_wm_hints_get_input(hints))
+ *accepts_focus = 1;
+ else
+ *accepts_focus = 0;
+ }
+ if ((flags & XCB_WM_HINT_STATE) && (initial_state))
+ {
+ if (xcb_wm_hints_get_initial_state(hints) == XCB_WM_STATE_WITHDRAWN)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (xcb_wm_hints_get_initial_state(hints) == XCB_WM_STATE_NORMAL)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (xcb_wm_hints_get_initial_state(hints) == XCB_WM_STATE_ICONIC)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+ if ((flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
+ {
+ *icon_pixmap = xcb_wm_hints_get_icon_pixmap(hints);
+ }
+ if ((flags & XCB_WM_HINT_ICON_MASK) && (icon_mask))
+ {
+ *icon_mask = xcb_wm_hints_get_icon_mask(hints);
+ }
+ if ((flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window))
+ {
+ *icon_window = xcb_wm_hints_get_icon_window(hints);
+ }
+ if ((flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group))
+ {
+ if (reply->value_len < XCB_NUM_WM_HINTS_ELEMENTS)
+ *window_group = 0;
+ else
+ *window_group = xcb_wm_hints_get_window_group(hints);
+ }
+ if ((flags & XCB_WM_HINT_X_URGENCY) && (is_urgent))
+ {
+ *is_urgent = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_size_pos_hints_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_NORMAL_HINTS,
+ ECORE_X_ATOM_WM_SIZE_HINTS,
+ 0L, 18);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_size_pos_hints_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_size_pos_hints_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Sets the hints of a window.
+ * @param window The window.
+ * @param request_pos Request position flag.
+ * @param gravity Gravity.
+ * @param min_w Minimum width.
+ * @param min_h Minimum height.
+ * @param max_w Maximum width.
+ * @param max_h Maximum height.
+ * @param base_w Base width
+ * @param base_h Base height
+ * @param step_x X step coordinate.
+ * @param step_y Y step coordinate.
+ * @param min_aspect Minimum aspect ratio.
+ * @param max_aspect Maximum aspect ratio.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_size_pos_hints_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_size_pos_hints_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_size_pos_hints_set(Ecore_X_Window window,
+ int request_pos,
+ Ecore_X_Gravity gravity,
+ int min_w,
+ int min_h,
+ int max_w,
+ int max_h,
+ int base_w,
+ int base_h,
+ int step_x,
+ int step_y,
+ double min_aspect,
+ double max_aspect)
+{
+ xcb_size_hints_t hint;
+ xcb_get_property_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply ||
+ (reply->type != ECORE_X_ATOM_WM_SIZE_HINTS) ||
+ ((reply->format != 8) &&
+ (reply->format != 16) &&
+ (reply->format != 32)) ||
+ (reply->value_len < 15))
+ return;
+
+ xcb_size_hints_set_flags(&hint, 0);
+ if (request_pos)
+ {
+ xcb_size_hints_set_flags(&hint, XCB_SIZE_HINT_US_POSITION);
+ }
+ if (gravity != ECORE_X_GRAVITY_NW)
+ {
+ xcb_size_hints_set_win_gravity(&hint, (uint8_t)gravity);
+ }
+ if ((min_w > 0) || (min_h > 0))
+ {
+ xcb_size_hints_set_min_size(&hint, min_w, min_h);
+ }
+ if ((max_w > 0) || (max_h > 0))
+ {
+ xcb_size_hints_set_max_size(&hint, max_w, max_h);
+ }
+ if ((base_w > 0) || (base_h > 0))
+ {
+ xcb_size_hints_set_base_size(&hint, base_w, base_h);
+ }
+ if ((step_x > 1) || (step_y > 1))
+ {
+ xcb_size_hints_set_resize_inc(&hint, step_x, step_y);
+ }
+ if ((min_aspect > 0.0) || (max_aspect > 0.0))
+ {
+ xcb_size_hints_set_aspect(&hint,
+ (int32_t)(min_aspect * 10000),
+ 10000,
+ (int32_t)(max_aspect * 10000),
+ 10000);
+ }
+ xcb_set_wm_normal_hints(_ecore_xcb_conn, window, &hint);
+}
+
+/**
+ * Gets the hints of a window.
+ * @param window The window.
+ * @param request_pos Request position flag.
+ * @param gravity Gravity.
+ * @param min_w Minimum width.
+ * @param min_h Minimum height.
+ * @param max_w Maximum width.
+ * @param max_h Maximum height.
+ * @param base_w Base width
+ * @param base_h Base height
+ * @param step_x X step coordinate.
+ * @param step_y Y step coordinate.
+ * @param min_aspect Minimum aspect ratio.
+ * @param max_aspect M
+ * @return 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_size_pos_hints_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_size_pos_hints_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI int
+ecore_x_icccm_size_pos_hints_get(Ecore_X_Window window __UNUSED__,
+ int *request_pos,
+ Ecore_X_Gravity *gravity,
+ int *min_w,
+ int *min_h,
+ int *max_w,
+ int *max_h,
+ int *base_w,
+ int *base_h,
+ int *step_x,
+ int *step_y,
+ double *min_aspect,
+ double *max_aspect)
+{
+ xcb_size_hints_t hint;
+ xcb_get_property_reply_t *reply;
+ uint32_t flags;
+ int32_t minw = 0;
+ int32_t minh = 0;
+ int32_t maxw = 32767;
+ int32_t maxh = 32767;
+ int32_t basew = -1;
+ int32_t baseh = -1;
+ int32_t stepx = -1;
+ int32_t stepy = -1;
+ double mina = 0.0;
+ double maxa = 0.0;
+
+ if (request_pos) *request_pos = 0;
+ if (gravity) *gravity = ECORE_X_GRAVITY_NW;
+ if (min_w) *min_w = minw;
+ if (min_h) *min_h = minh;
+ if (max_w) *max_w = maxw;
+ if (max_h) *max_h = maxh;
+ if (base_w) *base_w = basew;
+ if (base_h) *base_h = baseh;
+ if (step_x) *step_x = stepx;
+ if (step_y) *step_y = stepy;
+ if (min_aspect) *min_aspect = mina;
+ if (max_aspect) *max_aspect = maxa;
+
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ if (!_ecore_x_icccm_size_hints_get(reply, ECORE_X_ATOM_WM_NORMAL_HINTS, &hint))
+ return 0;
+
+ flags = xcb_size_hints_get_flags(hint);
+ if ((flags & XCB_SIZE_HINT_US_POSITION) || (flags & XCB_SIZE_HINT_P_POSITION))
+ {
+ if (request_pos)
+ *request_pos = 1;
+ }
+ if (flags & XCB_SIZE_HINT_P_WIN_GRAVITY)
+ {
+ if (gravity)
+ *gravity = xcb_size_hints_get_win_gravity(&hint);
+ }
+ if (flags & XCB_SIZE_HINT_P_MIN_SIZE)
+ {
+ xcb_size_hints_get_min_size(hint, &minw, &minh);
+ }
+ if (flags & XCB_SIZE_HINT_P_MAX_SIZE)
+ {
+ xcb_size_hints_get_max_size(&hint, &maxw, &maxh);
+ if (maxw < minw)
+ maxw = minw;
+ if (maxh < minh)
+ maxh = minh;
+ }
+ if (flags & XCB_SIZE_HINT_BASE_SIZE)
+ {
+ xcb_size_hints_get_base_size(&hint, &basew, &baseh);
+ if (basew > minw)
+ minw = basew;
+ if (baseh > minh)
+ minh = baseh;
+ }
+ if (flags & XCB_SIZE_HINT_P_RESIZE_INC)
+ {
+ xcb_size_hints_get_increase(&hint, &stepx, &stepy);
+ if (stepx < 1)
+ stepx = 1;
+ if (stepy < 1)
+ stepy = 1;
+ }
+ if (flags & XCB_SIZE_HINT_P_ASPECT)
+ {
+ int32_t min_aspect_num;
+ int32_t min_aspect_den;
+ int32_t max_aspect_num;
+ int32_t max_aspect_den;
+
+ xcb_size_hints_get_min_aspect(hint, &min_aspect_num, &min_aspect_den);
+ if (min_aspect_den > 0)
+ mina = ((double)min_aspect_num) / ((double)min_aspect_den);
+ xcb_size_hints_get_max_aspect(hint, &max_aspect_num, &max_aspect_den);
+ if (max_aspect_den > 0)
+ maxa = ((double)max_aspect_num) / ((double)max_aspect_den);
+ }
+
+ if (min_w)
+ *min_w = minw;
+ if (min_h)
+ *min_h = minh;
+ if (max_w)
+ *max_w = maxw;
+ if (max_h)
+ *max_h = maxh;
+ if (base_w)
+ *base_w = basew;
+ if (base_h)
+ *base_h = baseh;
+ if (step_x)
+ *step_x = stepx;
+ if (step_y)
+ *step_y = stepy;
+ if (min_aspect)
+ *min_aspect = mina;
+ if (max_aspect)
+ *max_aspect = maxa;
+
+ return 1;
+}
+
+/**
+ * Set the title of a window
+ * @param window The window.
+ * @param title The title.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_title_set(Ecore_X_Window window,
+ const char *title)
+{
+ if (!title) return;
+
+ /* FIXME: to do: utf8 */
+
+/* xprop.value = NULL; */
+/* #ifdef X_HAVE_UTF8_STRING */
+/* list[0] = strdup(t); */
+/* ret = */
+/* Xutf8TextListToTextProperty(_ecore_xcb_conn, list, 1, XUTF8StringStyle, */
+/* &xprop); */
+/* #else */
+/* list[0] = strdup(t); */
+/* ret = */
+/* XmbTextListToTextProperty(_ecore_xcb_conn, list, 1, XStdICCTextStyle, */
+/* &xprop); */
+/* #endif */
+
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_NAME, ECORE_X_ATOM_STRING, 8,
+ strlen(title), title);
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_title_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_NAME,
+ XCB_GET_PROPERTY_TYPE_ANY,
+ 0L, 128);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_title_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_title_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Gets the title of a window.
+ * @param window The window (Unused).
+ * @return The title of the window
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_title_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_title_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI char *
+ecore_x_icccm_title_get(Ecore_X_Window window __UNUSED__)
+{
+ char *title = NULL;
+ xcb_get_property_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return NULL;
+
+ if (reply->type == ECORE_X_ATOM_UTF8_STRING)
+ {
+ int length;
+
+ /* FIXME: verify the value of length */
+ length = (reply->value_len * reply->format) / 8;
+ title = (char *)malloc((length + 1) * sizeof(char));
+ memcpy(title, xcb_get_property_value(reply), length);
+ title[length] = '\0';
+ }
+ /* not in UTF8, so we convert */
+ else
+ {
+ /* convert to utf8 */
+
+ /* FIXME: to do... */
+
+/* #ifdef X_HAVE_UTF8_STRING */
+/* ret = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xprop, */
+/* &list, &num); */
+/* #else */
+/* ret = XmbTextPropertyToTextList(_ecore_xcb_conn, &xprop, */
+/* &list, &num); */
+/* #endif */
+
+/* if ((ret == XLocaleNotSupported) || */
+/* (ret == XNoMemory) || (ret == XConverterNotFound)) */
+/* { */
+/* t = strdup((char *)xprop.value); */
+/* } */
+/* else if ((ret >= Success) && (num > 0)) */
+/* { */
+/* t = strdup(list[0]); */
+/* } */
+/* if (list) */
+/* XFreeStringList(list); */
+/* } */
+
+/* if (xprop.value) XFree(xprop.value); */
+ }
+
+ return title;
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_protocol_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_ATOM_ATOM, 0, 1000000L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_protocol_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_protocol_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Set or unset a wm protocol property.
+ * @param window The Window
+ * @param protocol The protocol to enable/disable
+ * @param on On/Off
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_protocol_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_protocol_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_protocol_set(Ecore_X_Window window,
+ Ecore_X_WM_Protocol protocol,
+ int on)
+{
+ xcb_get_property_reply_t *reply;
+ Ecore_X_Atom *protos = NULL;
+ Ecore_X_Atom proto;
+ uint32_t protos_count = 0;
+ uint8_t already_set = 0;
+
+ /* Check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return;
+
+ proto = _ecore_xcb_atoms_wm_protocols[protocol];
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ if ((reply->type == ECORE_X_ATOM_ATOM) && (reply->format == 32))
+ {
+ uint32_t i;
+
+ protos_count = reply->value_len / sizeof(Ecore_X_Atom);
+ protos = (Ecore_X_Atom *)xcb_get_property_value(reply);
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ already_set = 1;
+ break;
+ }
+ }
+ }
+
+ if (on)
+ {
+ Ecore_X_Atom *new_protos = NULL;
+
+ if (already_set)
+ return;
+ new_protos = (Ecore_X_Atom *)malloc((protos_count + 1) * sizeof(Ecore_X_Atom));
+ if (!new_protos)
+ return;
+ memcpy(new_protos, protos, reply->value_len);
+ new_protos[protos_count] = proto;
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_ATOM_ATOM, 32,
+ protos_count + 1, new_protos);
+ free(new_protos);
+ }
+ else
+ {
+ uint32_t i;
+
+ if (!already_set)
+ return;
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ uint32_t j;
+
+ for (j = i + 1; j < protos_count; j++)
+ protos[j - 1] = protos[j];
+ if (protos_count > 1)
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_ATOM_ATOM, 32,
+ protos_count - 1, protos);
+ else
+ xcb_delete_property(_ecore_xcb_conn, window,
+ ECORE_X_ATOM_WM_PROTOCOLS);
+ return;
+ }
+ }
+ }
+}
+
+/**
+ * Determines whether a protocol is set for a window.
+ * @param window The Window (Unused).
+ * @param protocol The protocol to query.
+ * @return 1 if the protocol is set, else 0.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_protocol_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_protocol_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI int
+ecore_x_icccm_protocol_isset(Ecore_X_Window window __UNUSED__,
+ Ecore_X_WM_Protocol protocol)
+{
+ xcb_get_property_reply_t *reply;
+ Ecore_X_Atom *protos = NULL;
+ Ecore_X_Atom proto;
+ uint32_t i;
+ uint8_t ret = 0;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return 0;
+
+ proto = _ecore_xcb_atoms_wm_protocols[protocol];
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply || (reply->type != ECORE_X_ATOM_ATOM) || (reply->format != 32))
+ {
+ return 0;
+ }
+
+ protos = (Ecore_X_Atom *)xcb_get_property_value(reply);
+ for (i = 0; i < reply->value_len; i++)
+ if (protos[i] == proto)
+ {
+ ret = 1;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * Set a window name & class.
+ * @param window The window
+ * @param name The name string
+ * @param class The class string
+ *
+ * Set the name and class of @p window to respectively @p name and @p class.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_name_class_set(Ecore_X_Window window,
+ const char *name,
+ const char *class)
+{
+ char *class_string;
+ char *s;
+ int length_name;
+ int length_class;
+
+ length_name = strlen(name);
+ length_class = strlen(class);
+ class_string = (char *)malloc(sizeof(char) * (length_name + length_class + 2));
+ if (!class_string)
+ return;
+ s = class_string;
+ if (length_name)
+ {
+ strcpy(s, name);
+ s += length_name + 1;
+ }
+ else
+ *s++ = '\0';
+ if(length_class)
+ strcpy(s, class);
+ else
+ *s = '\0';
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8,
+ length_name + length_class + 2, (void *)class_string);
+ free(class_string);
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_name_class_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_CLASS,
+ ECORE_X_ATOM_STRING,
+ 0, 2048L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_name_class_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_name_class_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get a window name and class.
+ * @param window The window (Unused).
+ * @param name The name string.
+ * @param class The class string.
+ *
+ * Store the name and class of @p window into respectively @p name and
+ * @p class.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_name_class_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_name_class_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_name_class_get(Ecore_X_Window window __UNUSED__,
+ char **name,
+ char **class)
+{
+ xcb_get_property_reply_t *reply;
+ void *data;
+ char *n = NULL;
+ char *c = NULL;
+ int length;
+ int length_name;
+ int length_class;
+
+
+ if (name) *name = NULL;
+ if (class) *class = NULL;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return;
+
+ if ((reply->type != ECORE_X_ATOM_STRING) ||
+ (reply->format != 8))
+ return;
+
+ length = reply->value_len;
+ data = xcb_get_property_value(reply);
+ /* data contains the name string and the class string */
+ /* separated by the NULL character. data is not NULL-terminated */
+ length_name = strlen(data);
+ n = (char *)malloc(sizeof(char) * (length_name + 1));
+ if (!n)
+ return;
+ length_class = length - length_name - 1;
+ c = (char *)malloc(sizeof(char) * (length_class + 1));
+ if (!c)
+ {
+ free(n);
+ return;
+ }
+
+ memcpy(n, data, length_name);
+ n[length_name] = '\0';
+ length_class = length - length_name - 1;
+ data += length_name + 1;
+ memcpy(c, data, length_class);
+ c[length_class] = '\0';
+
+ if (name)
+ *name = n;
+ if (class)
+ *class = c;
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_client_machine_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ ECORE_X_ATOM_WM_CLIENT_MACHINE,
+ XCB_GET_PROPERTY_TYPE_ANY,
+ 0L, 1000000L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_client_machine_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_client_machine_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get a window client machine string.
+ * @param window The window
+ * @return The windows client machine string
+ *
+ * Return the client machine of a window. String must be free'd when done with.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_client_machine_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_client_machine_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI char *
+ecore_x_icccm_client_machine_get(Ecore_X_Window window)
+{
+ char *name;
+
+ name = ecore_x_window_prop_string_get(window, ECORE_X_ATOM_WM_CLIENT_MACHINE);
+ return name;
+}
+
+/**
+ * Sets the WM_COMMAND property for @a win.
+ *
+ * @param window The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_command_set(Ecore_X_Window window,
+ int argc,
+ char **argv)
+{
+ void *buf;
+ char *b;
+ int nbytes;
+ int i;
+
+ for (i = 0, nbytes = 0; i < argc; i++)
+ {
+ nbytes += strlen(argv[i]) + 1;
+ }
+ buf = malloc(sizeof(char) * nbytes);
+ if (!buf)
+ return;
+ b = (char *)buf;
+ for (i = 0; i < argc; i++)
+ {
+ if (argv[i])
+ {
+ strcpy(b, argv[i]);
+ b += strlen(argv[i]) + 1;
+ }
+ else
+ *b++ = '\0';
+ }
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8,
+ nbytes, buf);
+ free(buf);
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_command_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_COMMAND,
+ XCB_GET_PROPERTY_TYPE_ANY,
+ 0L, 1000000L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_command_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_command_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the WM_COMMAND property for a window.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ *
+ * Return the command of @p window and store it in @p argv. @p argc
+ * contains the number of arguments. String must be free'd when done with.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_command_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_command_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_command_get(Ecore_X_Window window __UNUSED__,
+ int *argc,
+ char ***argv)
+{
+ xcb_get_property_reply_t *reply;
+ char **v;
+ char *data;
+ char *cp;
+ char *start;
+ uint32_t value_len;
+ int c;
+ int i;
+ int j;
+
+ if (argc) *argc = 0;
+ if (argv) *argv = NULL;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return;
+
+ if ((reply->type != ECORE_X_ATOM_STRING) ||
+ (reply->format != 8))
+ return;
+
+ value_len = reply->value_len;
+ data = (char *)xcb_get_property_value(reply);
+ if (value_len && (data[value_len - 1] == '\0'))
+ value_len--;
+
+ c = 1;
+ for (cp = (char *)data, i = value_len; i > 0; cp++, i--)
+ {
+ if (*cp == '\0') c++;
+ }
+ v = (char **)malloc((c + 1) * sizeof(char *));
+ if (!v)
+ return;
+
+ start = (char *)malloc((value_len + 1) * sizeof(char));
+ if (!start)
+ {
+ free(v);
+ return;
+ }
+
+ memcpy (start, (char *) data, value_len);
+ start[value_len] = '\0';
+ for (cp = start, i = value_len + 1, j = 0; i > 0; cp++, i--) {
+ if (*cp == '\0') {
+ v[j] = start;
+ start = (cp + 1);
+ j++;
+ }
+ }
+
+ if (c < 1)
+ {
+ if (v)
+ free(v);
+ return;
+ }
+
+ if (argc) *argc = c;
+ if (argv)
+ {
+ (*argv) = malloc(c * sizeof(char *));
+ if (!*argv)
+ {
+ free(v);
+ if (argc) *argc = 0;
+ return;
+ }
+ for (i = 0; i < c; i++)
+ {
+ if (v[i])
+ (*argv)[i] = strdup(v[i]);
+ else
+ (*argv)[i] = strdup("");
+ }
+ }
+
+ free(v);
+}
+
+/**
+ * Set a window icon name.
+ * @param window The window.
+ * @param title The icon name string.
+ *
+ * Set @p window icon name.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_icon_name_set(Ecore_X_Window window,
+ const char *title)
+{
+ /* FIXME: do the UTF8 conversion... */
+
+/* #ifdef X_HAVE_UTF8_STRING */
+/* list[0] = strdup(t); */
+/* ret = Xutf8TextListToTextProperty(_ecore_xcb_conn, list, 1, */
+/* XUTF8StringStyle, &xprop); */
+/* #else */
+/* list[0] = strdup(t); */
+/* ret = XmbTextListToTextProperty(_ecore_xcb_conn, list, 1, */
+/* XStdICCTextStyle, &xprop); */
+/* #endif */
+
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_ICON_NAME, ECORE_X_ATOM_WM_ICON_NAME,
+ 8, strlen(title), title);
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_icon_name_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_ICON_NAME,
+ XCB_GET_PROPERTY_TYPE_ANY,
+ 0L, 128L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_icon_name_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_icon_name_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get a window icon name.
+ * @param window The window.
+ * @return The windows icon name string.
+ *
+ * Return the icon name of @p window. String must be free'd when done with.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_icon_name_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_icon_name_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI char *
+ecore_x_icccm_icon_name_get(Ecore_X_Window window __UNUSED__)
+{
+ xcb_get_property_reply_t *reply;
+ char *title = NULL;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return NULL;
+
+ ERR("reply->bytes_afer (should be 0): %d", ((xcb_get_property_reply_t *)reply)->bytes_after);
+
+ if (reply->type == ECORE_X_ATOM_UTF8_STRING)
+ {
+ int length;
+
+ /* FIXME: verify the value of length */
+ length = reply->value_len * reply->format / 8;
+ title = (char *)malloc((length + 1) * sizeof(char));
+ memcpy(title, xcb_get_property_value(reply), length);
+ title[length] = '\0';
+ }
+ /* not in UTF8, so we convert */
+ else
+ {
+ /* FIXME: do the UTF8... */
+
+ /* convert to utf8 */
+/* #ifdef X_HAVE_UTF8_STRING */
+/* ret = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xprop, */
+/* &list, &num); */
+/* #else */
+/* ret = XmbTextPropertyToTextList(_ecore_xcb_conn, &xprop, */
+/* &list, &num); */
+/* #endif */
+
+/* if ((ret == XLocaleNotSupported) || */
+/* (ret == XNoMemory) || (ret == XConverterNotFound)) */
+/* { */
+/* t = strdup((char *)xprop.value); */
+/* } */
+/* else if (ret >= Success) */
+/* { */
+/* if ((num >= 1) && (list)) */
+/* { */
+/* t = strdup(list[0]); */
+/* } */
+/* if (list) */
+/* XFreeStringList(list); */
+/* } */
+/* } */
+
+/* if (xprop.value) XFree(xprop.value); */
+ }
+
+ return title;
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_colormap_window_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? ((xcb_screen_t *)_ecore_xcb_screen)->root : window,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ ECORE_X_ATOM_WINDOW,
+ 0L, LONG_MAX);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_colormap_window_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_colormap_window_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Add a subwindow to the list of windows that need a different colormap installed.
+ * @param window The toplevel window
+ * @param sub_window The subwindow to be added to the colormap windows list
+ *
+ * Add @p sub_window to the list of windows that need a different
+ * colormap installed.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_colormap_window_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_colormap_window_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_colormap_window_set(Ecore_X_Window window,
+ Ecore_X_Window sub_window)
+{
+ void *data = NULL;
+ xcb_get_property_reply_t *reply;
+ uint32_t num;
+
+ if (window == 0)
+ window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply || (reply->format != 32) || (reply->value_len == 0))
+ {
+ data = calloc(1, sizeof(Ecore_X_Window));
+ if (!data)
+ {
+ if (reply) free(reply);
+ return;
+ }
+ num = 1;
+ }
+ else
+ {
+ Ecore_X_Window *newset = NULL;
+ Ecore_X_Window *oldset = NULL;
+ uint32_t i;
+
+ num = reply->value_len;
+ data = calloc(num + 1, sizeof(Ecore_X_Window));
+ if (!data)
+ return;
+
+ newset = (Ecore_X_Window *)data;
+ oldset = (Ecore_X_Window *)xcb_get_property_value(reply);
+ for (i = 0; i < num; ++i)
+ {
+ if (oldset[i] == sub_window)
+ {
+ free(newset);
+ return;
+ }
+
+ newset[i] = oldset[i];
+ }
+
+ newset[num++] = sub_window;
+ }
+
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ ECORE_X_ATOM_WINDOW,
+ 32, num, data);
+ free(data);
+}
+
+/**
+ * Remove a window from the list of colormap windows.
+ * @param window The toplevel window
+ * @param sub_window The window to be removed from the colormap window list.
+ *
+ * Remove @p sub_window from the list of colormap windows.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_colormap_window_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_colormap_window_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_colormap_window_unset(Ecore_X_Window window,
+ Ecore_X_Window sub_window)
+{
+ void *data = NULL;
+ Ecore_X_Window *oldset = NULL;
+ Ecore_X_Window *newset = NULL;
+ xcb_get_property_reply_t *reply;
+ uint32_t num;
+ uint32_t i;
+ uint32_t j;
+ uint32_t k = 0;
+
+ if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply || (reply->format != 32) || (reply->value_len == 0))
+ return;
+
+ num = reply->value_len;
+ oldset = (Ecore_X_Window *)xcb_get_property_value(reply);
+ for (i = 0; i < num; i++)
+ {
+ if (oldset[i] == sub_window)
+ {
+ if (num == 1)
+ {
+ xcb_delete_property(_ecore_xcb_conn, window,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
+ return;
+ }
+ else
+ {
+ data = calloc(num - 1, sizeof(Ecore_X_Window));
+ newset = (Ecore_X_Window *)data;
+ for (j = 0; j < num; ++j)
+ if (oldset[j] != sub_window)
+ newset[k++] = oldset[j];
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ ECORE_X_ATOM_WINDOW,
+ 32, k, data);
+ free(newset);
+ return;
+ }
+ }
+ }
+}
+
+/**
+ * Specify that a window is transient for another top-level window and should be handled accordingly.
+ * @param window The transient window
+ * @param forwindow The toplevel window
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_transient_for_set(Ecore_X_Window window,
+ Ecore_X_Window forwindow)
+{
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32,
+ 1, (void *)&forwindow);
+}
+
+/**
+ * Remove the transient_for setting from a window.
+ * @param window The window.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_transient_for_unset(Ecore_X_Window window)
+{
+ xcb_delete_property(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_TRANSIENT_FOR);
+}
+
+/*
+ * Sends the GetProperty request.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_transient_for_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_WM_TRANSIENT_FOR,
+ ECORE_X_ATOM_WINDOW,
+ 0L, 1L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_transient_for_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_transient_for_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the window this window is transient for, if any.
+ * @param window The window to check (Unused).
+ * @return The window ID of the top-level window, or 0 if the property does not exist.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_transient_for_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_transient_for_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_icccm_transient_for_get(Ecore_X_Window window __UNUSED__)
+{
+ xcb_get_property_reply_t *reply;
+ Ecore_X_Window forwin = 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return forwin;
+
+ if ((reply->format != 32) ||
+ (reply->value_len == 0) ||
+ (reply->type != ECORE_X_ATOM_WINDOW))
+ return forwin;
+
+ forwin = *(Ecore_X_Window *)xcb_get_property_value(reply);
+
+ return forwin;
+}
+
+/**
+ * Set the window role hint.
+ * @param window The window
+ * @param role The role string.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_window_role_set(Ecore_X_Window window,
+ const char *role)
+{
+ ecore_x_window_prop_string_set(window, ECORE_X_ATOM_WM_WINDOW_ROLE,
+ (char *)role);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_window_role_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ ECORE_X_ATOM_WM_WINDOW_ROLE, XCB_GET_PROPERTY_TYPE_ANY,
+ 0L, 1000000L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_window_role_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_window_role_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the window role.
+ * @param window The window.
+ * @return The window's role string.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_window_role_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_window_role_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI char *
+ecore_x_icccm_window_role_get(Ecore_X_Window window)
+{
+ return ecore_x_window_prop_string_get(window, ECORE_X_ATOM_WM_WINDOW_ROLE);
+}
+
+/**
+ * Set the window's client leader.
+ * @param window The window
+ * @param leader The client leader window
+ *
+ * All non-transient top-level windows created by an app other than
+ * the main window must have this property set to the app's main window.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_client_leader_set(Ecore_X_Window window,
+ Ecore_X_Window leader)
+{
+ ecore_x_window_prop_window_set(window, ECORE_X_ATOM_WM_CLIENT_LEADER,
+ &leader, 1);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_client_leader_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window,
+ ECORE_X_ATOM_WM_CLIENT_LEADER,
+ ECORE_X_ATOM_WINDOW,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_icccm_client_leader_get_prefetch().
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_client_leader_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the window's client leader.
+ * @param window The window
+ * @return The window's client leader window, or 0 if unset.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_icccm_client_leader_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_icccm_client_leader_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_icccm_client_leader_get(Ecore_X_Window window)
+{
+ Ecore_X_Window leader;
+
+ if (ecore_x_window_prop_window_get(window, ECORE_X_ATOM_WM_CLIENT_LEADER,
+ &leader, 1) > 0)
+ return leader;
+
+ return 0;
+}
+
+/**
+ * Send the ClientMessage event with the ChangeState property.
+ * @param window The window.
+ * @param root The root window.
+ * @ingroup Ecore_X_ICCCM_Group
+ */
+EAPI void
+ecore_x_icccm_iconic_request_send(Ecore_X_Window window,
+ Ecore_X_Window root)
+{
+ xcb_client_message_event_t ev;
+
+ if (!window) return;
+ if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ /* send_event is bit 7 (0x80) of response_type */
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 32;
+ ev.sequence = 0;
+ ev.window = window;
+ ev.type = ECORE_X_ATOM_WM_CHANGE_STATE;
+ ev.data.data32[0] = XCB_WM_STATE_ICONIC;
+
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
+ (const char *)&ev);
+}
+
+/* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */
+/* hints. each should go in their own file/section so we know which */
+/* is which. also older kde hints too. we should try support as much */
+/* as makese sense to support */
--- /dev/null
+/*
+ * Various MWM related functions.
+ *
+ * This is ALL the code involving anything MWM related. for both WM and
+ * client.
+ */
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+/**
+ * @defgroup Ecore_X_MWM_Group MWM related functions.
+ *
+ * Functions related to MWM.
+ */
+
+#define ECORE_X_MWM_HINTS_FUNCTIONS (1 << 0)
+#define ECORE_X_MWM_HINTS_DECORATIONS (1 << 1)
+#define ECORE_X_MWM_HINTS_INPUT_MODE (1 << 2)
+#define ECORE_X_MWM_HINTS_STATUS (1 << 3)
+
+typedef struct _mwmhints
+{
+ uint32_t flags;
+ uint32_t functions;
+ uint32_t decorations;
+ int32_t inputmode;
+ uint32_t status;
+}
+MWMHints;
+
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose MWM hints are requested.
+ * @ingroup Ecore_X_MWM_Group
+ */
+EAPI void
+ecore_x_mwm_hints_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 0, LONG_MAX);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_mwm_hints_get_prefetch().
+ * @ingroup Ecore_X_MWM_Group
+ */
+EAPI void
+ecore_x_mwm_hints_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * To document.
+ * @param window Unused.
+ * @param fhint To document.
+ * @param dhint To document.
+ * @param ihint To document.
+ * @return 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_mwm_hints_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_mwm_hints_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_MWM_Group
+ */
+EAPI int
+ecore_x_mwm_hints_get(Ecore_X_Window window __UNUSED__,
+ Ecore_X_MWM_Hint_Func *fhint,
+ Ecore_X_MWM_Hint_Decor *dhint,
+ Ecore_X_MWM_Hint_Input *ihint)
+{
+ MWMHints *mwmhints = NULL;
+ int ret = 0;
+ xcb_get_property_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ if ((reply->format != 32) ||
+ (reply->value_len == 0))
+ return 0;
+
+ mwmhints = xcb_get_property_value(reply);
+ if (reply->value_len >= 4)
+ {
+ if (dhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_DECORATIONS)
+ *dhint = mwmhints->decorations;
+ else
+ *dhint = ECORE_X_MWM_HINT_DECOR_ALL;
+ }
+ if (fhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_FUNCTIONS)
+ *fhint = mwmhints->functions;
+ else
+ *fhint = ECORE_X_MWM_HINT_FUNC_ALL;
+ }
+ if (ihint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_INPUT_MODE)
+ *ihint = mwmhints->inputmode;
+ else
+ *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS;
+ }
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Sets the borderless flag of a window using MWM.
+ * @param window The window.
+ * @param borderless The borderless flag.
+ * @ingroup Ecore_X_MWM_Group
+ */
+EAPI void
+ecore_x_mwm_borderless_set(Ecore_X_Window window,
+ int borderless)
+{
+ uint32_t data[5] = {0, 0, 0, 0, 0};
+
+ data[0] = 2; /* just set the decorations hint! */
+ data[2] = !borderless;
+
+ if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_MOTIF_WM_HINTS, ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 32, 5, data);
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+/**
+ * @defgroup Ecore_X_NetWM_Group Extended Window Manager Hint (EWMH) functions
+ *
+ * Functions related to the Extended Window Manager Hint (EWMH).
+ */
+
+
+typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
+
+struct _Ecore_X_Startup_Info
+{
+ Ecore_X_Window win;
+
+ int init;
+
+ int buffer_size;
+ char *buffer;
+
+ int length;
+
+ /* These are the sequence info fields */
+ char *id;
+ char *name;
+ int screen;
+ char *bin;
+ char *icon;
+ int desktop;
+ int timestamp;
+ char *description;
+ char *wmclass;
+ int silent;
+};
+
+#if 0
+static void _ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window, Ecore_X_Atom atom);
+static void _ecore_x_window_prop_string_utf8_get_fetch(void);
+#endif
+static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window window, Ecore_X_Atom atom, const char *str);
+static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window window, Ecore_X_Atom atom);
+#if 0 /* Unused */
+static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info);
+static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, char *data);
+#endif
+static void _ecore_x_netwm_startup_info_free(void *data);
+
+/*
+ * Local variables
+ */
+
+static Eina_Hash *startup_info = NULL;
+
+/**
+ * Initialize the NetWM module
+ */
+EAPI void
+ecore_x_netwm_init(void)
+{
+ startup_info = eina_hash_string_superfast_new(_ecore_x_netwm_startup_info_free);
+}
+
+/**
+ * Shutdown the NetWM module
+ */
+EAPI void
+ecore_x_netwm_shutdown(void)
+{
+ if (startup_info)
+ eina_hash_free(startup_info);
+ startup_info = NULL;
+}
+
+/**
+ * Set the _NET_SUPPORTING_WM_CHECK property.
+ * @param root The root window.
+ * @param check The child window.
+ * @param wm_name The name of the Window Manager.
+ *
+ * Set the _NET_SUPPORTING_WM_CHECK property on the @p root window to be
+ * the ID of the child window @p check created by the Window Manager.
+ * @p check also have the _NET_WM_NAME property set to the name
+ * @p wm_name of the Window Manager.
+ *
+ * The Window MUST call that function to indicate that a compliant
+ * window manager is active.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_wm_identify(Ecore_X_Window root,
+ Ecore_X_Window check,
+ const char *wm_name)
+{
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
+ ecore_x_window_prop_window_set(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
+ _ecore_x_window_prop_string_utf8_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name);
+ /* This one isn't mandatory */
+ _ecore_x_window_prop_string_utf8_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name);
+}
+
+/**
+ * Set the _NET_SUPPORTED property.
+ * @param root The root window.
+ * @param supported The supported hints.
+ * @param num The number of hints.
+ *
+ * Set the _NET_SUPPORTED property on the @p root window. The hints
+ * that the Window Manager supports are stored in @p supported.
+ *
+ * The Window Manager MUST set this property to indicate which hints
+ * it supports.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_supported_set(Ecore_X_Window root,
+ Ecore_X_Atom *supported,
+ int num)
+{
+ ecore_x_window_prop_atom_set(root, ECORE_X_ATOM_NET_SUPPORTED, supported, num);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param root The root window
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_supported_get_prefetch(Ecore_X_Window root)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, root,
+ ECORE_X_ATOM_NET_SUPPORTED, ECORE_X_ATOM_ATOM,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_supported_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_supported_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the hints supported by the Window Manager.
+ * @param root The root window.
+ * @param supported The supported hints.
+ * @param num The number of atoms.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Get the hints supported by the Window Manager. @p root is the root
+ * window. The hints are stored in @p supported. The number of hints
+ * is stored in @p num.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_supported_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_supported_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_supported_get(Ecore_X_Window root,
+ Ecore_X_Atom **supported,
+ int *num)
+{
+ int num_ret;
+
+ if (num) *num = 0UL;
+ if (supported) *supported = NULL;
+
+ num_ret = ecore_x_window_prop_xid_list_get(root,
+ ECORE_X_ATOM_NET_SUPPORTED,
+ ECORE_X_ATOM_ATOM,
+ supported);
+ if (num_ret <= 0)
+ return 0;
+
+ if (num) *num = (uint32_t)num_ret;
+ return 1;
+}
+
+/**
+ * Set the _NET_NUMBER_OF_DESKTOPS property.
+ * @param root The root window.
+ * @param n_desks The number of desktops.
+ *
+ * Set the number of desktops @p n_desks of the Window Manager by
+ * sending the _NET_NUMBER_OF_DESKTOPS to the @p root window.
+ *
+ * The Window Manager SHOULD set and update this property to indicate
+ * the number of virtual desktops. A Pager can request a change in the
+ * number of desktops by using that function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_count_set(Ecore_X_Window root,
+ unsigned int n_desks)
+{
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
+ &n_desks, 1);
+}
+
+/**
+ * Set the _NET_VIRTUAL_ROOTS property.
+ * @param root The root window.
+ * @param vroots The virtual root windows.
+ * @param n_desks The number of desks.
+ *
+ * Set the number of virtual desktops by sending the
+ * _NET_VIRTUAL_ROOTS property to the @p root window. @p vroots is an
+ * array of window and @p n_desks is the number of windows.
+ *
+ * A Window Manager that implements virtual desktops by reparent
+ * client windows to a child of the root window MUST use that
+ * function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
+ Ecore_X_Window *vroots,
+ unsigned int n_desks)
+{
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, vroots, n_desks);
+}
+
+/**
+ * Set the _NET_DESKTOP_NAMES property.
+ * @param root The root window.
+ * @param names The names of the virtual desktops.
+ * @param n_desks The number of virtual desktops.
+ *
+ * Set the name of each virtual desktop by sending the
+ * _NET_DESKTOP_NAMES to the @p root window. @p names are the names of
+ * the virtual desktops and @p n_desks is the number of virtual
+ * desktops.
+ *
+ * A Pager MAY use that function. @p n_desks may be different from the
+ * one passed to ecore_x_netwm_desk_count_set(). If it less or equal,
+ * then the desktops with high numbers are unnamed. If it is larger,
+ * then the excess names are considered to be reserved in case the
+ * number of desktops is increased.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_names_set(Ecore_X_Window root,
+ const char **names,
+ unsigned int n_desks)
+{
+ char ss[32];
+ char *buf;
+ const char *s;
+ uint32_t i;
+ uint32_t len;
+ uint32_t l;
+
+ buf = NULL;
+ len = 0;
+
+ for (i = 0; i < n_desks; i++)
+ {
+ s = (names) ? names[i] : NULL;
+ if (!s)
+ {
+ /* Default to "Desk-<number>" */
+ sprintf(ss, "Desk-%d", i);
+ s = ss;
+ }
+
+ l = strlen(s) + 1;
+ buf = realloc(buf, len + l);
+ memcpy(buf + len, s, l);
+ len += l;
+ }
+
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, root,
+ ECORE_X_ATOM_NET_DESKTOP_NAMES,
+ ECORE_X_ATOM_UTF8_STRING,
+ 8, len, (const void *)buf);
+ free(buf);
+}
+
+/**
+ * Set the _NET_DESKTOP_GEOMETRY property.
+ * @param root The root window.
+ * @param width The width of the desktop.
+ * @param height The height of the desktop.
+ *
+ * Set the common @p width and @p height of all desktops by sending
+ * the _NET_DESKTOP_GEOMETRY to the @p root window.
+ *
+ * This size is equal to the screen size if the Window Manager doesn't
+ * support large desktops, otherwise it's equal to the virtual size of
+ * the desktop. The Window Manager SHOULD set this property. A Pager
+ * can request a change in the desktop geometry by using this
+ * function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_size_set(Ecore_X_Window root,
+ unsigned int width,
+ unsigned int height)
+{
+ uint32_t size[2];
+
+ size[0] = width;
+ size[1] = height;
+ ecore_x_window_prop_card32_set(root,
+ ECORE_X_ATOM_NET_DESKTOP_GEOMETRY,
+ size, 2);
+}
+
+/**
+ * Set the _NET_DESKTOP_VIEWPORT property.
+ * @param root The root window.
+ * @param origins An array of paris of coordiantes.
+ * @param n_desks The number of virtual desktops.
+ *
+ * Set the top left corner of each desktop's viewport by sending the
+ * _NET_DESKTOP_VIEWPORT property to the @p root window. @p origins
+ * contains each pair of X coordinate and Y coordinate of the top left
+ * corner of each desktop's viewport.
+ *
+ * If the Window Manager does not support large desktops, the
+ * coordinates MUST be (0,0). A Pager can request to change the
+ * viewport for the current desktop by using this function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
+ unsigned int *origins,
+ unsigned int n_desks)
+{
+ ecore_x_window_prop_card32_set(root,
+ ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
+ origins, 2 * n_desks);
+}
+
+/**
+ * Set the _NET_DESKTOP_LAYOUT property.
+ * @param root The root window.
+ * @param orientation
+ * @param columns
+ * @param rows
+ * @param starting_corner
+ *
+ * Set the layout of virtual desktops relative to each other by
+ * sending the _NET_DESKTOP_LAYOUT to the @p root window.
+ * @p orientation defines the orientation of the virtual desktop. 0
+ * means horizontal layout, 1 means vertical layout. @p columns is
+ * the number of desktops in the X direction and @p rows is the number
+ * in the Y direction. @p starting_corner is the corner containing the
+ * first desktop. The values for @p starting_corner are 0 (top-left),
+ * 1 (top-right), 2 (bottom-right) and 3 (bottom-left).
+ *
+ * When the orientation is horizontal the desktops are laid out in
+ * rows, with the first desktop in the specified starting corner. So a
+ * layout with four columns and three rows starting in
+ * the top-left corner looks like this:
+ *
+ * +--+--+--+--+
+ * | 0| 1| 2| 3|
+ * +--+--+--+--+
+ * | 4| 5| 6| 7|
+ * +--+--+--+--+
+ * | 8| 9|10|11|
+ * +--+--+--+--+
+ *
+ * With @p starting_corner being bottom-right, it looks like this:
+ *
+ * +--+--+--+--+
+ * |11|10| 9| 8|
+ * +--+--+--+--+
+ * | 7| 6| 5| 4|
+ * +--+--+--+--+
+ * | 3| 2| 1| 0|
+ * +--+--+--+--+
+ *
+ * When the orientation is vertical the layout with four columns and
+ * three rows starting in the top-left corner looks like:
+ *
+ * +--+--+--+--+
+ * | 0| 3| 6| 9|
+ * +--+--+--+--+
+ * | 1| 4| 7|10|
+ * +--+--+--+--+
+ * | 2| 5| 8|11|
+ * +--+--+--+--+
+ *
+ * With @p starting_corner being top-right, it looks like:
+ *
+ * +--+--+--+--+
+ * | 9| 6| 3| 0|
+ * +--+--+--+--+
+ * |10| 7| 4| 1|
+ * +--+--+--+--+
+ * |11| 8| 5| 2|
+ * +--+--+--+--+
+ *
+ * This function MUST be used by a Pager and NOT by the Window
+ * Manager. When using this function, the Pager must own a manager
+ * selection.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_layout_set(Ecore_X_Window root,
+ int orientation,
+ int columns,
+ int rows,
+ int starting_corner)
+{
+ uint32_t layout[4];
+
+ layout[0] = orientation;
+ layout[1] = columns;
+ layout[2] = rows;
+ layout[3] = starting_corner;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT, layout, 4);
+}
+
+/**
+ * Set the _NET_WORKAREA property.
+ * @param root The root window.
+ * @param areas An array of areas.
+ * @param n_desks The number of desks.
+ *
+ * Set the work area for each desktop by sending the _NET_WORKAREA
+ * property to the @p root window. An area contains the geometry (X
+ * and Y coordinates, width and height). These geometries are
+ * specified relative to the viewport on each desktop and specify an
+ * area that is completely contained within the viewport. @p areas
+ * stores these geometries. @p n_desks is the number of geometry to
+ * set.
+ *
+ * This function MUST be set by the Window Manager. It is used by
+ * desktop applications to place desktop icons appropriately.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
+ unsigned int *areas,
+ unsigned int n_desks)
+{
+ ecore_x_window_prop_card32_set(root,
+ ECORE_X_ATOM_NET_WORKAREA,
+ areas, 4 * n_desks);
+}
+
+/**
+ * Set the _NET_CURRENT_DESKTOP property.
+ * @param root The root window.
+ * @param desk The index of the current desktop.
+ *
+ * Set the current desktop by sending the _NET_CURRENT_DESKTOP to the
+ * @p root window. @p deskmust be an integer number between 0 and the
+ * number of desks (set by ecore_x_netwm_desk_count_set()) -1.
+ *
+ * This function MUST be called by the Window Manager. If a Pagerwants
+ * to switch to naother desktop, it MUST call that function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desk_current_set(Ecore_X_Window root,
+ unsigned int desk)
+{
+ ecore_x_window_prop_card32_set(root,
+ ECORE_X_ATOM_NET_CURRENT_DESKTOP,
+ &desk, 1);
+}
+
+/**
+ * Set the _NET_SHOWING_DESKTOP property.
+ * @param root The root window
+ * @param on 0 to hide the desktop, non 0 to show it.
+ *
+ * Set or unset the desktop in a "showing mode" by sending the
+ * _NET_SHOWING_DESKTOP property to the @p root window. If @p on is 0,
+ * the windows are hidden and the desktop background is displayed and
+ * focused.
+ *
+ * If a Pager wants to enter or leave the mode, it MUST use this
+ * function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_showing_desktop_set(Ecore_X_Window root,
+ int on)
+{
+ uint32_t val;
+
+ val = (on) ? 1 : 0;
+ ecore_x_window_prop_card32_set(root,
+ ECORE_X_ATOM_NET_SHOWING_DESKTOP,
+ &val, 1);
+}
+
+/*
+ * Client status
+ */
+
+/**
+ * Set the _NET_CLIENT_LIST property.
+ * @param root The root window.
+ * @param p_clients An array of windows.
+ * @param n_clients The number of windows.
+ *
+ * Map all the X windows managed by the window manager from the oldest
+ * to the newest by sending the _NET_CLIENT_LIST property to the
+ * @p root window. The X windows are stored in @p p_clients and their
+ * number in @p n_clients.
+ *
+ * This function SHOULD be called by the Window Manager.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_client_list_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients,
+ unsigned int n_clients)
+{
+ ecore_x_window_prop_window_set(root,
+ ECORE_X_ATOM_NET_CLIENT_LIST,
+ p_clients, n_clients);
+}
+
+/**
+ * Set the _NET_CLIENT_LIST_STACKING property.
+ * @param root The root window.
+ * @param p_clients An array of windows.
+ * @param n_clients The number of windows.
+ *
+ * Stack all the X windows managed by the window manager from bottom
+ * to top order by sending the _NET_CLIENT_LIST_STACKING property to the
+ * @p root window. The X windows are stored in @p p_clients and their
+ * number in @p n_clients.
+ *
+ * This function SHOULD be called by the Window Manager.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients,
+ unsigned int n_clients)
+{
+ ecore_x_window_prop_window_set(root,
+ ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
+ p_clients, n_clients);
+}
+
+/**
+ * Set the _NET_ACTIVE_WINDOW property.
+ * @param root The root window.
+ * @param window The widow to activate.
+ *
+ * Activate @p window by sending the _NET_ACTIVE_WINDOW property to
+ * the @p root window.
+ *
+ * If a Client wants to activate another window, it MUST call this
+ * function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_client_active_set(Ecore_X_Window root,
+ Ecore_X_Window window)
+{
+ ecore_x_window_prop_window_set(root,
+ ECORE_X_ATOM_NET_ACTIVE_WINDOW,
+ &window, 1);
+}
+
+/**
+ * Set the _NET_WM_NAME property.
+ * @param window The widow to activate.
+ * @param name The title name of the window.
+ *
+ * Set the title name of @p window to @p name by sending the
+ * _NET_WM_NAME property to @p window.
+ *
+ * The Client SHOULD set the title of @p window in UTF-8 encoding. If
+ * set, the Window Manager should use this in preference to WM_NAME.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_name_set(Ecore_X_Window window,
+ const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_NAME, name);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_name_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_NAME, ECORE_X_ATOM_UTF8_STRING,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_name_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_name_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the title of a window.
+ * @param window The window.
+ * @param name The title name.
+ * @return Returns always 1.
+ *
+ * Retrieve the title name of @p window and store it in @p name. The
+ * function returns always 1.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_name_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_name_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_name_get(Ecore_X_Window window,
+ char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_WM_NAME);
+ return 1;
+}
+
+/**
+ * Set the _NET_STARTUP_ID property.
+ * @param window The window.
+ * @param id The ID name.
+ *
+ * Set the ID @p id used for the startup sequence by sending the
+ * property _NET_STARTUP_ID to @p window. The ID name should be
+ * encoded in UTF-8.
+ *
+ * If a new value for the property is set, the Window Manager
+ * should update the window's status accordingly (update its virtual
+ * desktop, etc.).
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_startup_id_set(Ecore_X_Window window,
+ const char *id)
+{
+ _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_STARTUP_ID, id);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_startup_id_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_STARTUP_ID, ECORE_X_ATOM_UTF8_STRING,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_startup_id_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_startup_id_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the startup ID name of a window.
+ * @param window The window
+ * @param id The ID name
+ * @return Return always 1.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_startup_id_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_startup_id_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_startup_id_get(Ecore_X_Window window,
+ char **id)
+{
+ if (id)
+ *id = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_STARTUP_ID);
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_VISIBLE_NAME property.
+ * @param window The widow to activate.
+ * @param name The title name of the window.
+ *
+ * Set the title name of @p window to @p name by sending the
+ * _NET_WM_VISIBLE_NAME property to @p window, when the Window Manager
+ * displays a window name other than by calling
+ * ecore_x_netwm_name_set().
+ *
+ * The Client SHOULD set the title of @p window in UTF-8
+ * encoding. This function is used for displaying title windows like
+ * [xterm1], [xterm2], ... thereby allowing Pagers to display the same
+ * title as the Window Manager.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_visible_name_set(Ecore_X_Window window,
+ const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
+ name);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_visible_name_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_VISIBLE_NAME, ECORE_X_ATOM_UTF8_STRING,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_name_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_visible_name_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the visible title of a window.
+ * @param window The window.
+ * @param name The title name.
+ * @return Returns always 1.
+ *
+ * Retrieve the visible title name of @p window and store it in @p name. The
+ * function returns always 1.
+ * @param window The window
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_visible_name_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_visible_name_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_visible_name_get(Ecore_X_Window window,
+ char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(window,
+ ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_ICON_NAME property.
+ * @param window The widow to activate.
+ * @param name The icon name of the window.
+ *
+ * Set the icon name of @p window to @p name by sending the
+ * _NET_WM_ICON_NAME property to @p window.
+ *
+ * The Client SHOULD set the title of @p window in UTF-8 encoding. If
+ * set, the Window Manager should use this in preference to WM_ICON_NAME.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icon_name_set(Ecore_X_Window window,
+ const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_ICON_NAME,
+ name);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icon_name_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_ICON_NAME, ECORE_X_ATOM_UTF8_STRING,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_icon_name_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icon_name_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the icon name of a window.
+ * @param window The window.
+ * @param name The icon name.
+ * @return Returns always 1.
+ *
+ * Retrieve the icon name of @p window and store it in @p name. The
+ * function returns always 1.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_icon_name_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_icon_name_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_icon_name_get(Ecore_X_Window window,
+ char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(window,
+ ECORE_X_ATOM_NET_WM_ICON_NAME);
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_VISIBLE_ICON_NAME property.
+ * @param window The widow to activate.
+ * @param name The title name of the window.
+ *
+ * Set the icon name of @p window to @p name by sending the
+ * _NET_WM_VISIBLE_ICON_NAME property to @p window, when the Window Manager
+ * displays a icon name other than by calling
+ * ecore_x_netwm_icon_name_set().
+ *
+ * The Client SHOULD set the icon name in UTF-8
+ * encoding. The Window Manager MUST use this function is it display
+ * an icon name other than with ecore_x_netwm_icon_name_set().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_visible_icon_name_set(Ecore_X_Window window,
+ const char *name)
+{
+ _ecore_x_window_prop_string_utf8_set(window,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
+ name);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_visible_icon_name_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME, ECORE_X_ATOM_UTF8_STRING,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_icon_name_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_visible_icon_name_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the visible icon name of a window.
+ * @param window The window.
+ * @param name The icon name.
+ * @return Returns always 1.
+ *
+ * Retrieve the visible icon name of @p window and store it in
+ * @p name. The function returns always 1.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_visible_icon_name_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_visible_icon_name_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_visible_icon_name_get(Ecore_X_Window window,
+ char **name)
+{
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(window,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_DESKTOP property.
+ * @param window The window.
+ * @param desk The desktop index.
+ *
+ * Set on which desktop the @p window is in by sending the
+ * _NET_WM_DESKTOP property to @p window. @p desk is the index of
+ * the desktop, starting from 0. To indicate that the window should
+ * appear on all desktops, @p desk must be equal to 0xFFFFFFFF.
+ *
+ * A Client MAY choose not to set this property, in which case the
+ * Window Manager SHOULD place it as it wishes.
+ *
+ * The Window Manager should honor _NET_WM_DESKTOP whenever a
+ * withdrawn window requests to be mapped.
+ *
+ * A Client can request a change of desktop for a non-withdrawn window
+ * by sending a _NET_WM_DESKTOP client message to the root window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desktop_set(Ecore_X_Window window,
+ unsigned int desk)
+{
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desktop_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_DESKTOP, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_desktop_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desktop_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the visible icon name of a window.
+ * @param window The window.
+ * @param desk The desktop index.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the desktop index in which @p window is displayed and
+ * store it in @p desk. If @p desk value is 0xFFFFFFFF, the window
+ * appears on all desktops. The function returns 1 on success, 0
+ * otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_desktop_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_desktop_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_desktop_get(Ecore_X_Window window,
+ unsigned int *desk)
+{
+ int ret;
+ uint32_t tmp;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_DESKTOP,
+ &tmp, 1);
+
+ if (desk) *desk = tmp;
+ return (ret == 1) ? 1 : 0;
+}
+
+/**
+ * Set the _NET_WM_STRUT property.
+ * @param window The window
+ * @param left The number of pixels at the left of the screen.
+ * @param right The number of pixels at the right of the screen.
+ * @param top The number of pixels at the top of the screen.
+ * @param bottom The number of pixels at the bottom of the screen.
+ *
+ * Set space at the edje of the screen by sending the _NET_WM_STRUT
+ * property to @p window if @p window is to reserve that space.
+ * @p left, @p right, @p top and @p bottom are respectively the number
+ * of pixels at the left, right, top and bottom of the screen.
+ *
+ * This property is deprecated and ecore_x_netwm_strut_partial_set()
+ * should be used instead. However, Clients MAY set this property in
+ * addition to _NET_WM_STRUT_PARTIAL to ensure backward compatibility
+ * with Window Managers supporting older versions of the
+ * Specification.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_strut_set(Ecore_X_Window window,
+ int left,
+ int right,
+ int top,
+ int bottom)
+{
+ uint32_t strut[4];
+
+ strut[0] = left;
+ strut[1] = right;
+ strut[2] = top;
+ strut[3] = bottom;
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_strut_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_STRUT, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_strut_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_strut_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/*
+ * _NET_WM_STRUT is deprecated
+ */
+
+/**
+ * Get the space at the edje of the screen.
+ * @param window The window
+ * @param left The number of pixels at the left of the screen.
+ * @param right The number of pixels at the right of the screen.
+ * @param top The number of pixels at the top of the screen.
+ * @param bottom The number of pixels at the bottom of the screen.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the space at the edje of the screen if @p window is to
+ * reserve such space. The number of pixels at the left, right, top
+ * and bottom of the screen are respectively stored in @p left,
+ * @p right, @p top and @p bottom. This function returns 1 on success,
+ * 0 otherwise.
+ *
+ * This property is deprecated. See ecore_x_netwm_strut_set() for more
+ * informations.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_strut_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_strut_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_strut_get(Ecore_X_Window window,
+ int *left,
+ int *right,
+ int *top,
+ int *bottom)
+{
+ uint32_t strut[4];
+ int ret = 0;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+ if (ret != 4)
+ return 0;
+
+ if (left) *left = strut[0];
+ if (right) *right = strut[1];
+ if (top) *top = strut[2];
+ if (bottom) *bottom = strut[3];
+
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_STRUT_PARTIAL property.
+ * @param window The window
+ * @param left The number of pixels at the left of the screen.
+ * @param right The number of pixels at the right of the screen.
+ * @param top The number of pixels at the top of the screen.
+ * @param bottom The number of pixels at the bottom of the screen.
+ * @param left_start_y The number of pixels.
+ * @param left_end_y The number of pixels.
+ * @param right_start_y The number of pixels.
+ * @param right_end_y The number of pixels.
+ * @param top_start_x The number of pixels.
+ * @param top_end_x The number of pixels.
+ * @param bottom_start_x The number of pixels.
+ * @param bottom_end_x The number of pixels.
+ *
+ * Set space at the edje of the screen by sending the
+ * _NET_WM_STRUT_PARTIAL property to @p window if @p window is to
+ * reserve that space. @p left, @p right, @p top and @p bottom are
+ * respectively the number of pixels at the left, right, top and
+ * bottom of the screen.
+ *
+ * TODO: more description for that function.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_strut_partial_set(Ecore_X_Window window,
+ int left,
+ int right,
+ int top,
+ int bottom,
+ int left_start_y,
+ int left_end_y,
+ int right_start_y,
+ int right_end_y,
+ int top_start_x,
+ int top_end_x,
+ int bottom_start_x,
+ int bottom_end_x)
+{
+ unsigned int strut[12];
+
+ strut[0] = left;
+ strut[1] = right;
+ strut[2] = top;
+ strut[3] = bottom;
+ strut[4] = left_start_y;
+ strut[5] = left_end_y;
+ strut[6] = right_start_y;
+ strut[7] = right_end_y;
+ strut[8] = top_start_x;
+ strut[9] = top_end_x;
+ strut[10] = bottom_start_x;
+ strut[11] = bottom_end_x;
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_strut_partial_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_strut_partial_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_strut_partial_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the space at the edje of the screen of a window.
+ * @param window The window
+ * @param left The number of pixels at the left of the screen.
+ * @param right The number of pixels at the right of the screen.
+ * @param top The number of pixels at the top of the screen.
+ * @param bottom The number of pixels at the bottom of the screen.
+ * @param left_start_y The number of pixels.
+ * @param left_end_y The number of pixels.
+ * @param right_start_y The number of pixels.
+ * @param right_end_y The number of pixels.
+ * @param top_start_x The number of pixels.
+ * @param top_end_x The number of pixels.
+ * @param bottom_start_x The number of pixels.
+ * @param bottom_end_x The number of pixels.
+ *
+ * Retrieve the space at the edje of the screen if @p window is to
+ * reserve such space. The number of pixels at the left, right, top
+ * and bottom of the screen are respectively stored in @p left,
+ * @p right, @p top and @p bottom. This function returns 1 on success,
+ * 0 otherwise.
+ *
+ * TODO: more description for that function.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_strut_partial_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_strut_partial_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_strut_partial_get(Ecore_X_Window window,
+ int *left,
+ int *right,
+ int *top,
+ int *bottom,
+ int *left_start_y,
+ int *left_end_y,
+ int *right_start_y,
+ int *right_end_y,
+ int *top_start_x,
+ int *top_end_x,
+ int *bottom_start_x,
+ int *bottom_end_x)
+{
+ uint32_t strut[12];
+ int ret = 0;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
+ if (ret != 12)
+ return 0;
+
+ if (left) *left = strut[0];
+ if (right) *right = strut[1];
+ if (top) *top = strut[2];
+ if (bottom) *bottom = strut[3];
+ if (left_start_y) *left_start_y = strut[4];
+ if (left_end_y) *left_end_y = strut[5];
+ if (right_start_y) *right_start_y = strut[6];
+ if (right_end_y) *right_end_y = strut[7];
+ if (top_start_x) *top_start_x = strut[8];
+ if (top_end_x) *top_end_x = strut[9];
+ if (bottom_start_x) *bottom_start_x = strut[10];
+ if (bottom_end_x) *bottom_end_x = strut[11];
+ return 1;
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icons_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_ICON, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_icons_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icons_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Retrieve hte possible icons of a window.
+ * @param window The window
+ * @param icon An array of icons.
+ * @param num The number of icons.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve an array of possible icons of @p window. The icons are
+ * stored in @p icon and their number in @p num.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_icons_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_icons_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_icons_get(Ecore_X_Window window,
+ Ecore_X_Icon **icon,
+ int *num)
+{
+ uint32_t *data;
+ uint32_t *p;
+ uint32_t *src;
+ uint32_t icons;
+ uint32_t len;
+ uint32_t i;
+ int num_ret;
+
+ if (num) *num = 0UL;
+ if (icon) *icon = NULL;
+
+ num_ret = ecore_x_window_prop_card32_list_get(window,
+ ECORE_X_ATOM_NET_WM_ICON,
+ &data);
+ if ((num_ret <= 0) || !data)
+ return 0;
+
+ if (num_ret < 2)
+ {
+ free(data);
+ return 0;
+ }
+
+ /* Check how many icons there are */
+ icons = 0;
+ p = data;
+ while (p)
+ {
+ len = p[0] * p[1];
+ p += (len + 2);
+ if ((p - data) > num_ret)
+ {
+ free(data);
+ return 0;
+ }
+ icons++;
+
+ if ((p - data) == num_ret)
+ p = NULL;
+ }
+ if (num) *num = icons;
+
+ /* If the user doesn't want the icons, return */
+ if (!icon)
+ {
+ free(data);
+ return 1;
+ }
+
+ /* Allocate memory */
+ *icon = malloc(icons * sizeof(Ecore_X_Icon));
+ if (!(*icon))
+ {
+ free(data);
+ return 0;
+ }
+
+ /* Fetch the icons */
+ p = data;
+ for (i = 0; i < icons; i++)
+ {
+ uint32_t *ps, *pd, *pe;
+
+ len = p[0] * p[1];
+ ((*icon)[i]).width = p[0];
+ ((*icon)[i]).height = p[1];
+ src = &(p[2]);
+ ((*icon)[i]).data = malloc(len * sizeof(uint32_t));
+ if (!((*icon)[i]).data)
+ {
+ while (i)
+ free(((*icon)[--i]).data);
+ free(*icon);
+ free(data);
+ return 0;
+ }
+
+ pd = ((*icon)[i]).data;
+ ps = src;
+ pe = ps + len;
+ for (; ps < pe; ps++)
+ {
+ uint32_t r, g, b, a;
+
+ a = (*ps >> 24) & 0xff;
+ r = (((*ps >> 16) & 0xff) * a) / 255;
+ g = (((*ps >> 8) & 0xff) * a) / 255;
+ b = (((*ps ) & 0xff) * a) / 255;
+ *pd = (a << 24) | (r << 16) | (g << 8) | (b);
+ pd++;
+ }
+ p += (len + 2);
+ }
+
+ free(data);
+
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_ICON_GEOMETRY property.
+ * @param window The window.
+ * @param x The X coordinate of the icon.
+ * @param y The Y coordinate of the icon.
+ * @param width The width of the icon.
+ * @param height The height of the icon.
+ *
+ * Set the geometry of the icon of @p window by sending the
+ * _NET_WM_ICON_GEOMETRY property to @p window. @p x, @p y, @p width
+ * and @p height specify respectively the X coordinate, the Y
+ * coordinate, the width and the height of the icon.
+ *
+ * Stand alone tools like a taskbar or an iconbox MAY use this
+ * function. This functions makes possible for a Window Manager to
+ * display a nice animation like morphing the window into its icon.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icon_geometry_set(Ecore_X_Window window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ uint32_t geometry[4];
+
+ geometry[0] = (uint32_t)x;
+ geometry[1] = (uint32_t)y;
+ geometry[2] = (uint32_t)width;
+ geometry[3] = (uint32_t)height;
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icon_geometry_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_icon_geometry_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_icon_geometry_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the geometry of an icon.
+ * @param window The window
+ * @param x x
+ * @param x The X coordinate of the icon.
+ * @param y The Y coordinate of the icon.
+ * @param width The width of the icon.
+ * @param height The height of the icon.
+ * @return 1 on success, 0 othrwise.
+ *
+ * Retrieve the geometry of the icon of @p window. The geometry is
+ * stored in @p x, @p y, @p width and @p height. The function returns
+ * 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_icon_geometry_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_icon_geometry_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_icon_geometry_get(Ecore_X_Window window,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+ uint32_t geometry[4];
+ int ret;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
+ if (ret != 4)
+ return 0;
+
+ if (x) *x = geometry[0];
+ if (y) *y = geometry[1];
+ if (width) *width = geometry[2];
+ if (height) *height = geometry[3];
+
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_PID property.
+ * @param window The window.
+ * @param pid The process ID.
+ *
+ * Set the process ID of the client owning @p window by sending the
+ * _NET_WM_PID property to @p window.
+ *
+ * This function MAY be used by the Window Manager to kill windows
+ * which do not respond to the _NET_WM_PING protocol.
+ *
+ * If _NET_WM_PID is set, the ICCCM-specified property
+ * WM_CLIENT_MACHINE MUST also be set.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_pid_set(Ecore_X_Window window,
+ int pid)
+{
+ unsigned int tmp;
+
+ tmp = pid;
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_pid_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_PID, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_pid_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_pid_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the process ID of a client window.
+ * @param window The window.
+ * @param pid The process ID.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the process ID of @p window and store it in @p pid. This
+ * function returns 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_pid_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_pid_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_pid_get(Ecore_X_Window window,
+ int *pid)
+{
+ int ret;
+ uint32_t tmp;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+ if (pid) *pid = tmp;
+
+ return (ret == 1) ? 1 : 0;
+}
+
+/**
+ * Set the _NET_WM_HANDLED_ICONS property.
+ * @param window The window.
+ *
+ * Indicate to the Window Manager that it does not need to provide
+ * icons for the iconified @p window by sending the
+ * _NET_WM_HANDLED_ICONS property to @p window.
+ *
+ * This function can be used by a Pager on one of its own toplevel
+ * windows (for example if the Client is a taskbar and provides
+ * buttons for iconified windows).
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_handled_icons_set(Ecore_X_Window window)
+{
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_handled_icons_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_HANDLED_ICONS, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_handled_icons_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_handled_icons_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Return wheter the Client handles icons or not.
+ * @param window The window.
+ * @return 1 if icons are handled, 0 otherwise.
+ *
+ * Return whether the client handles icons or not if @p window is
+ * iconified.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_handled_icons_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_handled_icons_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_handled_icons_get(Ecore_X_Window window)
+{
+ int ret = 0;
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+ return (ret == 0) ? 1 : 0;
+}
+
+/**
+ * Set the _NET_WM_USER_TIME property.
+ * @param window The window.
+ * @param time The last user activity time in the window.
+ *
+ * Set the XServer time at which last user activity in @p window took
+ * place by sending the _NET_WM_USER_TIME property to @p window. @p
+ * time contains that XServer time in seconds.
+ *
+ * This function allows a Window Manager to alter the focus, stacking,
+ * and/or placement behavior of windows when they are mapped depending
+ * on whether the new window was created by a user action or is a
+ * "pop-up" window activated by a timer or some other event.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_user_time_set(Ecore_X_Window window,
+ unsigned int time)
+{
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &time, 1);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_user_time_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_USER_TIME, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_user_time_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_user_time_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the last user activity time in the window.
+ * @param window The window.
+ * @param time The returned time.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Return the XServer time at which last user activity in @p window
+ * took place. The time is stored in @p time.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_user_time_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_user_time_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_user_time_get(Ecore_X_Window window,
+ unsigned int *time)
+{
+ int ret;
+ uint32_t tmp;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &tmp, 1);
+ if (time) *time = tmp;
+ return (ret == 1) ? 1 : 0;
+}
+
+Ecore_X_Window_State
+_ecore_x_netwm_state_get(Ecore_X_Atom a)
+{
+ if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
+ return ECORE_X_WINDOW_STATE_MODAL;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
+ return ECORE_X_WINDOW_STATE_STICKY;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
+ return ECORE_X_WINDOW_STATE_SHADED;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
+ return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
+ return ECORE_X_WINDOW_STATE_SKIP_PAGER;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
+ return ECORE_X_WINDOW_STATE_HIDDEN;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
+ return ECORE_X_WINDOW_STATE_FULLSCREEN;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
+ return ECORE_X_WINDOW_STATE_ABOVE;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
+ return ECORE_X_WINDOW_STATE_BELOW;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
+ return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
+ else
+ return ECORE_X_WINDOW_STATE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
+{
+ switch(s)
+ {
+ case ECORE_X_WINDOW_STATE_MODAL:
+ return ECORE_X_ATOM_NET_WM_STATE_MODAL;
+ case ECORE_X_WINDOW_STATE_STICKY:
+ return ECORE_X_ATOM_NET_WM_STATE_STICKY;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
+ return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
+ return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
+ case ECORE_X_WINDOW_STATE_SHADED:
+ return ECORE_X_ATOM_NET_WM_STATE_SHADED;
+ case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
+ return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
+ case ECORE_X_WINDOW_STATE_SKIP_PAGER:
+ return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
+ case ECORE_X_WINDOW_STATE_HIDDEN:
+ return ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
+ case ECORE_X_WINDOW_STATE_FULLSCREEN:
+ return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
+ case ECORE_X_WINDOW_STATE_ABOVE:
+ return ECORE_X_ATOM_NET_WM_STATE_ABOVE;
+ case ECORE_X_WINDOW_STATE_BELOW:
+ return ECORE_X_ATOM_NET_WM_STATE_BELOW;
+ case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
+ return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * Set the _NET_WM_STATE property.
+ * @param window The window.
+ * @param state An array of window hints.
+ * @param num The number of hints.
+ *
+ * Set a list of hints describing @p window state by sending the
+ * _NET_WM_STATE property to @p window. The hints are stored in the
+ * array @p state. @p num must contain the number of hints.
+ *
+ * The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn
+ * window requests to be mapped. A Client wishing to change the state
+ * of a window MUST send a _NET_WM_STATE client message to the root
+ * window. The Window Manager MUST keep this property updated to
+ * reflect the current state of the window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_window_state_set(Ecore_X_Window window,
+ Ecore_X_Window_State *state,
+ unsigned int num)
+{
+ Ecore_X_Atom *set;
+ uint32_t i;
+
+ if (!num)
+ {
+ ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_STATE);
+ return;
+ }
+
+ set = malloc(num * sizeof(Ecore_X_Atom));
+ if (!set) return;
+
+ for (i = 0; i < num; i++)
+ set[i] = _ecore_x_netwm_state_atom_get(state[i]);
+
+ ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_STATE, set, num);
+
+ free(set);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_window_state_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_STATE, ECORE_X_ATOM_ATOM,
+ 0, 0x7fffffff);;
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_state_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_window_state_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the hints describing the window state.
+ * @param window The window.
+ * @param state The returned hins.
+ * @param num The number of hints.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the hints describing @p window state. The state is
+ * returned in @p state. The nummber of hints is stored in @p
+ * num. This function returns 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_window_state_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_window_state_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_window_state_get(Ecore_X_Window window,
+ Ecore_X_Window_State **state,
+ unsigned int *num)
+{
+ Ecore_X_Atom *atoms;
+ int num_ret;
+ int i;
+
+ if (num) *num = 0;
+ if (state) *state = NULL;
+
+ num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_STATE,
+ &atoms);
+ if (num_ret <= 0)
+ return 0;
+
+ if (state)
+ {
+ *state = malloc(num_ret * sizeof(Ecore_X_Window_State));
+ if (*state)
+ for (i = 0; i < num_ret; ++i)
+ (*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
+
+ if (num) *num = num_ret;
+ }
+
+ free(atoms);
+
+ return 1;
+}
+
+static Ecore_X_Window_Type
+_ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
+ return ECORE_X_WINDOW_TYPE_DESKTOP;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
+ return ECORE_X_WINDOW_TYPE_DOCK;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
+ return ECORE_X_WINDOW_TYPE_TOOLBAR;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
+ return ECORE_X_WINDOW_TYPE_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
+ return ECORE_X_WINDOW_TYPE_UTILITY;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
+ return ECORE_X_WINDOW_TYPE_SPLASH;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
+ return ECORE_X_WINDOW_TYPE_DIALOG;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
+ return ECORE_X_WINDOW_TYPE_NORMAL;
+ else
+ return ECORE_X_WINDOW_TYPE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type)
+{
+ switch (type)
+ {
+ case ECORE_X_WINDOW_TYPE_DESKTOP:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
+ case ECORE_X_WINDOW_TYPE_DOCK:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
+ case ECORE_X_WINDOW_TYPE_TOOLBAR:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
+ case ECORE_X_WINDOW_TYPE_MENU:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
+ case ECORE_X_WINDOW_TYPE_UTILITY:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
+ case ECORE_X_WINDOW_TYPE_SPLASH:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
+ case ECORE_X_WINDOW_TYPE_DIALOG:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
+ case ECORE_X_WINDOW_TYPE_NORMAL:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
+ * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
+ */
+
+/**
+ * Set the _NET_WM_WINDOW_TYPE property.
+ * @param window The window.
+ * @param type The functional type of the window.
+ *
+ * Set the functional @p type of @p window by sending _NET_WM_WINDOW_TYPE
+ * property to @p window.
+ *
+ * This property SHOULD be set by the Client before mapping. This
+ * property SHOULD be used by the window manager in determining the
+ * decoration, stacking position and other behavior of the window. The
+ * Client SHOULD specify window types in order of preference (the first
+ * being most preferable).
+ *
+ * This hint is intended to replace the MOTIF hints.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_window_type_set(Ecore_X_Window window,
+ Ecore_X_Window_Type type)
+{
+ Ecore_X_Atom atom;
+
+ atom = _ecore_x_netwm_window_type_atom_get(type);
+ ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atom, 1);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_window_type_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE, ECORE_X_ATOM_ATOM,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_type_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_window_type_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/* FIXME: Maybe return 0 on some conditions? */
+
+/**
+ * Get the functional type of a window.
+ * @param window The window.
+ * @param type The function type of the window.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the functional type of @p window. The type is stored in
+ * @p type. This function returns 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_window_type_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_window_type_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_window_type_get(Ecore_X_Window window,
+ Ecore_X_Window_Type *type)
+{
+ Ecore_X_Atom *atoms;
+ int num;
+ int i;
+
+ if (type) *type = ECORE_X_WINDOW_TYPE_NORMAL;
+
+ num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atoms);
+ if (num < 0)
+ {
+ /* IMO this is not the place to mix netwm and icccm /kwo */
+ /* Check if WM_TRANSIENT_FOR is set */
+
+ /* Disable it for xcb */
+
+/* if ((type) && (ecore_x_icccm_transient_for_get(window))) */
+/* *type = ECORE_X_WINDOW_TYPE_DIALOG; */
+/* return 1; */
+ }
+
+ if (type)
+ {
+ for (i = 0; i < num; ++i)
+ {
+ *type = _ecore_x_netwm_window_type_type_get(atoms[i]);
+ if (*type != ECORE_X_WINDOW_TYPE_UNKNOWN)
+ break;
+ }
+ }
+
+ free(atoms);
+
+ return 1;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_action_atom_get(Ecore_X_Action action)
+{
+ switch (action)
+ {
+ case ECORE_X_ACTION_MOVE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
+ case ECORE_X_ACTION_RESIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
+ case ECORE_X_ACTION_MINIMIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
+ case ECORE_X_ACTION_SHADE:
+ return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
+ case ECORE_X_ACTION_STICK:
+ return ECORE_X_ATOM_NET_WM_ACTION_STICK;
+ case ECORE_X_ACTION_MAXIMIZE_HORZ:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
+ case ECORE_X_ACTION_MAXIMIZE_VERT:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
+ case ECORE_X_ACTION_FULLSCREEN:
+ return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
+ case ECORE_X_ACTION_CHANGE_DESKTOP:
+ return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
+ case ECORE_X_ACTION_CLOSE:
+ return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
+ case ECORE_X_ACTION_ABOVE:
+ return ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
+ case ECORE_X_ACTION_BELOW:
+ return ECORE_X_ATOM_NET_WM_ACTION_BELOW;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_allowed_action_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, ECORE_X_ATOM_ATOM,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_allowed_action_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_allowed_action_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/* FIXME: Get complete list */
+
+/**
+ * Check whether an action is supported by a window.
+ * @param window The window
+ * @param action The action
+ * @return 1 if set, 0 otherwise.
+ *
+ * Return whether the user operation @p action is supported by the
+ * Window Manager for @p window.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_allowed_action_isset(Ecore_X_Window window,
+ Ecore_X_Action action)
+{
+ Ecore_X_Atom *atoms;
+ Ecore_X_Atom atom;
+ int num;
+ int ret = 0;
+ int i;
+
+ num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ &atoms);
+ if (num <= 0)
+ return ret;
+
+ atom = _ecore_x_netwm_action_atom_get(action);
+
+ for (i = 0; i < num; ++i)
+ {
+ if (atom == atoms[i])
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ free(atoms);
+
+ return ret;
+}
+
+/* FIXME: Set complete list */
+/**
+ * Set the _NET_WM_ALLOWED_ACTIONS property.
+ * @param window The window.
+ * @param action An array of allowed actions.
+ * @param num The number of actions.
+ *
+ * Set the user operations that the Window Manager supports for
+ * @p window by sending the _NET_WM_ALLOWED_ACTIONS property to
+ * @p window. @p action stores @p num actions.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_allowed_action_set(Ecore_X_Window window,
+ Ecore_X_Action *action,
+ unsigned int num)
+{
+ Ecore_X_Atom *set;
+ unsigned int i;
+
+ if (!num)
+ {
+ ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
+ return;
+ }
+
+ set = malloc(num * sizeof(Ecore_X_Atom));
+ if (!set) return;
+
+ for (i = 0; i < num; i++)
+ set[i] = _ecore_x_netwm_action_atom_get(action[i]);
+
+ ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, set, num);
+
+ free(set);
+}
+
+/**
+ * Get the allowed actions supported by a window.
+ * @param window The window.
+ * @param action The returned array of the actions.
+ * @param num The number of actions.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the user operations that the Window Manager supports for
+ * @p window and store them in @p action. The number of actions is
+ * stored in @p num. This function returns 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_allowed_action_get(Ecore_X_Window window,
+ Ecore_X_Action **action,
+ unsigned int *num)
+{
+ Ecore_X_Atom *atoms;
+ int num_ret;
+ int i;
+
+ if (num) *num = 0;
+ if (action) *action = NULL;
+
+ num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ &atoms);
+ if (num_ret <= 0)
+ return 0;
+
+ if (action)
+ {
+ *action = malloc(num_ret * sizeof(Ecore_X_Action));
+ if (*action)
+ for (i = 0; i < num_ret; ++i)
+ (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
+
+ if (num) *num = num_ret;
+ }
+
+ free(atoms);
+
+ return 1;
+}
+
+/**
+ * Set the _NET_WM_WINDOW_OPACITY property.
+ * @param window The window.
+ * @param opacity The opacity value.
+ *
+ * Set the desired opacity of @p window by sending the
+ * _NET_WM_WINDOW_OPACITY property to @p window. @p opacity is 0 for a
+ * transparent window and 0xffffffff for an opaque window. @p opacity
+ * must be multiplied with the original alpha value of @p window
+ * (which is 1 for visuals not including an alpha component) so that
+ * @p window content is modulated by the opacity value.
+ *
+ * Window Managers acting as compositing managers MAY take this into
+ * account when displaying a window. Window Managers MUST forward the
+ * value of this property to any enclosing frame window. This
+ * property MAY change while the window is mapped and the Window
+ * Manager MUST respect changes while the window is mapped.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_opacity_set(Ecore_X_Window window,
+ unsigned int opacity)
+{
+ uint32_t op = opacity;
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &op, 1);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_opacity_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_opacity_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_opacity_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the opacity value of a window.
+ * @param window The window.
+ * @param opacity The returned opacity.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retriee the opacity value of @p window and store it in
+ * @p opacity. This function returns 1 on sucess, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_opacity_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_opacity_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_opacity_get(Ecore_X_Window window,
+ unsigned int *opacity)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &tmp, 1);
+ if (opacity) *opacity = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+/**
+ * Set the _NET_FRAME_EXTENTS property.
+ * @param window The window.
+ * @param fl The number of pixels of the left border of the window.
+ * @param fr The number of pixels of the right border of the window.
+ * @param ft The number of pixels of the top border of the window.
+ * @param fb The number of pixels of the bottom border of the window.
+ *
+ * Set the border witdh of @p window by sending the _NET_FRAME_EXTENTS
+ * property to @p window. @p fl, @p fr, @p ft and @p fb are respectively
+ * the number of pixels of the left, right, top and bottom border of
+ * @p window.
+ *
+ * The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of
+ * the window's frame.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_frame_size_set(Ecore_X_Window window,
+ int fl,
+ int fr,
+ int ft,
+ int fb)
+{
+ uint32_t frames[4];
+
+ frames[0] = fl;
+ frames[1] = fr;
+ frames[2] = ft;
+ frames[3] = fb;
+ ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_frame_size_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_FRAME_EXTENTS, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_frame_size_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_frame_size_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the frame extent of a window.
+ * @param window The window.
+ * @param fl The number of pixels of the left border of the window.
+ * @param fr The number of pixels of the right border of the window.
+ * @param ft The number of pixels of the top border of the window.
+ * @param fb The number of pixels of the bottom border of the window.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the frame extents of @p window. The number of pixels of
+ * the left, right, top and bottom border of @p window are
+ * respectively stored in @p fl, @p fr, @p ft anfd @p fb. TYhis
+ * function retuirns 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_frame_size_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_frame_size_get(Ecore_X_Window window,
+ int *fl,
+ int *fr,
+ int *ft,
+ int *fb)
+{
+ uint32_t frames[4];
+ int ret = 0;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
+ if (ret != 4)
+ return 0;
+
+ if (fl) *fl = frames[0];
+ if (fr) *fr = frames[1];
+ if (ft) *ft = frames[2];
+ if (fb) *fb = frames[3];
+ return 1;
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window The window.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_sync_counter_get_prefetch(Ecore_X_Window window)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_netwm_sync_counter_get_prefetch().
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_sync_counter_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get the X ID of a X Sync counter.
+ * @param window The window.
+ * @param counter The X ID of the Sync counter.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Retrieve the X ID of the X Sync counter of @p window and store it
+ * in @p counter. This function returns 1 on success, 0 otherwise.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_netwm_frame_size_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_netwm_sync_counter_get(Ecore_X_Window window,
+ Ecore_X_Sync_Counter *counter)
+{
+ int ret;
+ unsigned int tmp;
+
+ ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
+ &tmp, 1);
+
+ if (counter) *counter = tmp;
+ return (ret == 1) ? 1 : 0;
+}
+
+/**
+ * Send a _NET_WM_PING property event.
+ * @param window The window.
+ *
+ * Send a ClientMessage event from @p window with the _NET_WM_PING
+ * property set.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_ping_send(Ecore_X_Window window)
+{
+ xcb_client_message_event_t ev;
+
+ if (!window) return;
+
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 32;
+ ev.sequence = 0;
+ ev.window = window;
+ ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
+ ev.data.data32[0] = ECORE_X_ATOM_NET_WM_PING;
+ ev.data.data32[1] = _ecore_xcb_event_last_time;
+ ev.data.data32[2] = window;
+ ev.data.data32[3] = 0;
+ ev.data.data32[4] = 0;
+ ev.data.data32[5] = 0;
+
+ xcb_send_event(_ecore_xcb_conn, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+}
+
+/**
+ * Send a _NET_WM_SYNC_REQUEST property event.
+ * @param window The window.
+ * @param serial The update request number.
+ *
+ * Send a ClientMessage event from @p window with the _NET_WM_SYNC_REQUEST
+ * property set.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_sync_request_send(Ecore_X_Window window,
+ unsigned int serial)
+{
+ xcb_client_message_event_t ev;
+
+ if (!window) return;
+
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 32;
+ ev.window = window;
+ ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
+ ev.data.data32[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+ ev.data.data32[1] = _ecore_xcb_event_last_time;
+ ev.data.data32[2] = serial;
+ /* FIXME: imho, the following test is useless as serial is non negative */
+ /* should we remove it ? */
+ ev.data.data32[3] = (serial < 0) ? ~0L : 0L;
+ ev.data.data32[4] = 0;
+
+ xcb_send_event(_ecore_xcb_conn, 0, window, 0, (const char *)&ev);
+}
+
+/**
+ * Send a _NET_WM_STATE property event.
+ * @param window The window.
+ * @param root The root window.
+ * @param s1 The first state to alter.
+ * @param s2 The second state to alter.
+ * @param set 0 to unset the property, set it otherwise.
+ *
+ * Send a ClientMessage event from @p window to the @p root window
+ * with the _NET_WM_STATE property set. This change the state of a
+ * mapped window. @p s1 is the first state to alter. @p s2 is the
+ * second state to alter. If @p set value is 0, the property is
+ * removed (or unset), otherwise, the property is set.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_state_request_send(Ecore_X_Window window,
+ Ecore_X_Window root,
+ Ecore_X_Window_State s1,
+ Ecore_X_Window_State s2,
+ int set)
+{
+ xcb_client_message_event_t ev;
+
+ if (!window) return;
+ if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 32;
+ ev.window = window;
+ ev.type = ECORE_X_ATOM_NET_WM_STATE;
+ ev.data.data32[0] = !!set;
+ ev.data.data32[1] = _ecore_x_netwm_state_atom_get(s1);
+ ev.data.data32[2] = _ecore_x_netwm_state_atom_get(s2);
+ /* 1 == normal client, if someone wants to use this
+ * function in a pager, this should be 2 */
+ ev.data.data32[3] = 1;
+ ev.data.data32[4] = 0;
+
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
+ (const char *)&ev);
+}
+
+/**
+ * Send a _NET_WM_DESKTOP property event.
+ * @param window The window.
+ * @param root The root window.
+ * @param desktop The new desktop index.
+ *
+ * Send a ClientMessage event from @p window to the @p root window
+ * with the _NET_WM_DESKTOP property set. This change the state of a
+ * non-withdrawn window. @p desktop is the new desktop index to set.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI void
+ecore_x_netwm_desktop_request_send(Ecore_X_Window window,
+ Ecore_X_Window root,
+ unsigned int desktop)
+{
+ xcb_client_message_event_t ev;
+
+ if (!window) return;
+ if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
+ ev.format = 32;
+ ev.window = window;
+ ev.type = ECORE_X_ATOM_NET_WM_DESKTOP;
+ ev.data.data32[0] = desktop;
+
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
+ (const char *)&ev);
+}
+
+int
+_ecore_x_netwm_startup_info_begin(Ecore_X_Window window,
+ char *data)
+{
+#if 0
+ Ecore_X_Startup_Info *info;
+ unsigned char exists = 0;
+
+ if (!startup_info) return 0;
+ info = eina_hash_find(startup_info, (void *)window);
+ if (info)
+ {
+ exists = 1;
+ INF("Already got info for win: 0x%x", window);
+ _ecore_x_netwm_startup_info_free(info);
+ }
+ info = calloc(1, sizeof(Ecore_X_Startup_Info));
+ if (!info) return 0;
+ info->win = win;
+ info->length = 0;
+ info->buffer_size = 161;
+ info->buffer = calloc(info->buffer_size, sizeof(char));
+ if (!info->buffer)
+ {
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ memcpy(info->buffer, data, 20);
+ info->length += 20;
+ info->buffer[info->length] = 0;
+ if (exists)
+ eina_hash_modify(startup_info, (void *)info->win, info);
+ else
+ eina_hash_add(startup_info, (void *)info->win, info);
+ if (strlen(info->buffer) != 20)
+ {
+ /* We have a '\0' in there, the message is done */
+ _ecore_x_netwm_startup_info_process(info);
+ }
+#else
+ window = XCB_NONE;
+ data = NULL;
+#endif
+
+ return 1;
+}
+
+int
+_ecore_x_netwm_startup_info(Ecore_X_Window window,
+ char *data)
+{
+#if 0
+ Ecore_X_Startup_Info *info;
+ char *p;
+
+ if (!startup_info) return 0;
+ info = eina_hash_find(startup_info, (void *)window);
+ if (!info) return 0;
+ if ((info->length + 20) > info->buffer_size)
+ {
+ info->buffer_size += 160;
+ info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char));
+ if (!info->buffer)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ }
+ memcpy(info->buffer + info->length, data, 20);
+ p = info->buffer + info->length;
+ info->length += 20;
+ info->buffer[info->length] = 0;
+ if (strlen(p) != 20)
+ {
+ /* We have a '\0' in there, the message is done */
+ _ecore_x_netwm_startup_info_process(info);
+ }
+#else
+ window = XCB_NONE;
+ data = NULL;
+#endif
+
+ return 1;
+}
+
+/*
+ * Set UTF-8 string property
+ */
+static void
+_ecore_x_window_prop_string_utf8_set(Ecore_X_Window window,
+ Ecore_X_Atom atom,
+ const char *str)
+{
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ atom, ECORE_X_ATOM_UTF8_STRING,
+ 8, strlen(str), str);
+}
+
+static void
+_ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
+ atom, ECORE_X_ATOM_UTF8_STRING,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Get UTF-8 string property
+ * call _ecore_x_window_prop_string_utf8_get_prefetch() before.
+ */
+static char *
+_ecore_x_window_prop_string_utf8_get(Ecore_X_Window window __UNUSED__,
+ Ecore_X_Atom atom __UNUSED__)
+{
+ xcb_get_property_reply_t *reply;
+ char *str;
+ int length;
+
+ reply = _ecore_xcb_reply_get((Ecore_Xcb_Reply_Cb)xcb_get_property_reply);
+ if (!reply) return NULL;
+
+ if ((reply->format != 8) ||
+ (reply->value_len <= 0))
+ {
+ free(reply);
+ return NULL;
+ }
+
+ length = reply->value_len;
+ str = (char *)malloc (sizeof (char) * (length + 1));
+ if (!str)
+ {
+ free(reply);
+ return NULL;
+ }
+ memcpy(str, xcb_get_property_value(reply), length);
+ str[length] = '\0';
+
+ free(reply);
+ return str;
+}
+
+#if 0 /* Unused */
+/*
+ * Process startup info
+ */
+static int
+_ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
+{
+ Ecore_X_Event_Startup_Sequence *e;
+ int event;
+ char *p;
+
+ p = strchr(info->buffer, ':');
+ if (!p)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ *p = 0;
+ if (!strcmp(info->buffer, "new"))
+ {
+ if (info->init)
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
+ else
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
+ info->init = 1;
+ }
+ else if (!strcmp(info->buffer, "change"))
+ {
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
+ }
+ else if (!strcmp(info->buffer, "remove"))
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
+ else
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+
+ p++;
+
+ if (!_ecore_x_netwm_startup_info_parse(info, p))
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+
+ if (info->init)
+ {
+ e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence));
+ if (!e)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ e->win = info->win;
+ ecore_event_add(event, e, NULL, NULL);
+ }
+
+ if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ }
+ else
+ {
+ /* Discard buffer */
+ info->length = 0;
+ info->buffer[0] = 0;
+ }
+ return 1;
+}
+
+/*
+ * Parse startup info
+ */
+static int
+_ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
+ char *data)
+{
+
+ while (*data)
+ {
+ int in_quot_sing, in_quot_dbl, escaped;
+ char *p, *pp;
+ char *key;
+ char value[1024];
+
+ /* Skip space */
+ while (*data == ' ') data++;
+ /* Get key */
+ key = data;
+ data = strchr(key, '=');
+ if (!data) return 0;
+ *data = 0;
+ data++;
+
+ /* Get value */
+ p = data;
+ pp = value;
+ in_quot_dbl = 0;
+ in_quot_sing = 0;
+ escaped = 0;
+ while (*p)
+ {
+ if ((pp - value) >= 1024) return 0;
+ if (escaped)
+ {
+ *pp = *p;
+ pp++;
+ escaped = 0;
+ }
+ else if (in_quot_sing)
+ {
+ if (*p == '\\')
+ escaped = 1;
+ else if (*p == '\'')
+ in_quot_sing = 0;
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ else if (in_quot_dbl)
+ {
+ if (*p == '\\')
+ escaped = 1;
+ else if (*p == '\"')
+ in_quot_dbl = 0;
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ else
+ {
+ if (*p == '\\')
+ escaped = 1;
+ else if (*p == '\'')
+ in_quot_sing = 1;
+ else if (*p == '\"')
+ in_quot_dbl = 1;
+ else if (*p == ' ')
+ {
+ break;
+ }
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ p++;
+ }
+ if ((in_quot_dbl) || (in_quot_sing)) return 0;
+ data = p;
+ *pp = 0;
+
+ /* Parse info */
+ if (!strcmp(key, "ID"))
+ {
+ if ((info->id) && (strcmp(info->id, value))) return 0;
+ info->id = strdup(value);
+ p = strstr(value, "_TIME");
+ if (p)
+ {
+ info->timestamp = atoi(p + 5);
+ }
+ }
+ else if (!strcmp(key, "NAME"))
+ {
+ if (info->name) free(info->name);
+ info->name = strdup(value);
+ }
+ else if (!strcmp(key, "SCREEN"))
+ {
+ info->screen = atoi(value);
+ }
+ else if (!strcmp(key, "BIN"))
+ {
+ if (info->bin) free(info->bin);
+ info->bin = strdup(value);
+ }
+ else if (!strcmp(key, "ICON"))
+ {
+ if (info->icon) free(info->icon);
+ info->icon = strdup(value);
+ }
+ else if (!strcmp(key, "DESKTOP"))
+ {
+ info->desktop = atoi(value);
+ }
+ else if (!strcmp(key, "TIMESTAMP"))
+ {
+ if (!info->timestamp)
+ info->timestamp = atoi(value);
+ }
+ else if (!strcmp(key, "DESCRIPTION"))
+ {
+ if (info->description) free(info->description);
+ info->description = strdup(value);
+ }
+ else if (!strcmp(key, "WMCLASS"))
+ {
+ if (info->wmclass) free(info->wmclass);
+ info->wmclass = strdup(value);
+ }
+ else if (!strcmp(key, "SILENT"))
+ {
+ info->silent = atoi(value);
+ }
+ else
+ {
+ WRN("Ecore X Sequence, Unknown: %s=%s", key, value);
+ }
+ }
+ if (!info->id) return 0;
+ return 1;
+}
+#endif
+
+/*
+ * Free startup info struct
+ */
+static void
+_ecore_x_netwm_startup_info_free(void *data)
+{
+ Ecore_X_Startup_Info *info;
+
+ info = data;
+ if (!info) return;
+ if (info->buffer) free(info->buffer);
+ if (info->id) free(info->id);
+ if (info->name) free(info->name);
+ if (info->bin) free(info->bin);
+ if (info->icon) free(info->icon);
+ if (info->description) free(info->description);
+ if (info->wmclass) free(info->wmclass);
+ free(info);
+}
+
+/*
+ * Is screen composited?
+ */
+
+/* FIXME: one round trip can be removed. Can we keep it ? */
+
+/**
+ * Check whether a screen is composited or not.
+ * @param screen The screen index.
+ *
+ * Return 1 if @p screen is composited, 0 otherwise.
+ * @ingroup Ecore_X_NetWM_Group
+ */
+EAPI int
+ecore_x_screen_is_composited(int screen)
+{
+ char buf[32];
+ xcb_intern_atom_cookie_t cookie_atom;
+ xcb_get_selection_owner_cookie_t cookie_owner;
+ xcb_intern_atom_reply_t *reply_atom;
+ xcb_get_selection_owner_reply_t *reply_owner;
+ Ecore_X_Window window;
+ Ecore_X_Atom atom;
+
+ snprintf(buf, sizeof(buf), "_NET_WM_CM_S%d", screen);
+ cookie_atom = xcb_intern_atom_unchecked(_ecore_xcb_conn, 1,
+ strlen(buf), buf);
+ reply_atom = xcb_intern_atom_reply(_ecore_xcb_conn, cookie_atom, NULL);
+ if (!reply_atom) return 0;
+ atom = reply_atom->atom;
+ free(reply_atom);
+
+ cookie_owner = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, atom);
+ reply_owner = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie_owner, NULL);
+ if (!reply_owner) return 0;
+
+ window = reply_owner->owner;
+ free(reply_owner);
+
+ return window != XCB_NONE;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Pixmap_Group X Pixmap Functions
+ *
+ * Functions that operate on pixmaps.
+ */
+
+
+/**
+ * Creates a new pixmap.
+ * @param win Window used to determine which screen of the display the
+ * pixmap should be created on. If 0, the default root window
+ * is used.
+ * @param w Width of the new pixmap.
+ * @param h Height of the new pixmap.
+ * @param dep Depth of the pixmap. If 0, the default depth of the default
+ * screen is used.
+ * @return New pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI Ecore_X_Pixmap
+ecore_x_pixmap_new(Ecore_X_Window win,
+ int w,
+ int h,
+ int dep)
+{
+ Ecore_X_Pixmap pmap;
+
+ if (win == 0) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ if (dep == 0) dep = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth;
+
+ pmap = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn, dep, pmap, win, w, h);
+
+ return pmap;
+}
+
+
+/**
+ * Deletes the reference to the given pixmap.
+ *
+ * If no other clients have a reference to the given pixmap, the server
+ * will destroy it.
+ *
+ * @param pmap The given pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_free(Ecore_X_Pixmap pmap)
+{
+ xcb_free_pixmap(_ecore_xcb_conn, pmap);
+}
+
+
+/**
+ * Pastes a rectangular area of the given pixmap onto the given drawable.
+ * @param pmap The given pixmap.
+ * @param dest The given drawable.
+ * @param gc The graphics context which governs which operation will
+ * be used to paste the area onto the drawable.
+ * @param sx The X position of the area on the pixmap.
+ * @param sy The Y position of the area on the pixmap.
+ * @param w The width of the area.
+ * @param h The height of the area.
+ * @param dx The X position at which to paste the area on @p dest.
+ * @param dy The Y position at which to paste the area on @p dest.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_paste(Ecore_X_Pixmap pmap,
+ Ecore_X_Drawable dest,
+ Ecore_X_GC gc,
+ int sx,
+ int sy,
+ int w,
+ int h,
+ int dx,
+ int dy)
+{
+ xcb_copy_area(_ecore_xcb_conn, pmap, dest, gc, sx, sy, dx, dy, w, h);
+}
+
+
+/**
+ * Retrieves the size of the given pixmap.
+ * @param pmap The given pixmap.
+ * @param x Pointer to an integer in which to store the X position.
+ * @param y Pointer to an integer in which to store the Y position.
+ * @param w Pointer to an integer in which to store the width.
+ * @param h Pointer to an integer in which to store the height.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h)
+{
+ if (pmap)
+ ecore_x_drawable_geometry_get(pmap, x, y, w, h);
+}
+
+
+/**
+ * Retrieves the depth of the given pixmap.
+ * @param pmap The given pixmap.
+ * @return The depth of the pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI int
+ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap)
+{
+ return ecore_x_drawable_depth_get(pmap);
+}
--- /dev/null
+#ifndef __ECORE_XCB_PRIVATE_H__
+#define __ECORE_XCB_PRIVATE_H__
+
+#include "config.h"
+
+#include <sys/param.h>
+
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN 256
+#endif
+
+#ifndef XK_MISCELLANY
+# define XK_MISCELLANY 1
+#endif /* XK_MISCELLANY */
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_keysyms.h>
+#include <xcb/bigreq.h>
+#ifdef ECORE_XCB_CURSOR
+# include <xcb/cursor.h>
+#endif /* ECORE_XCB_CURSOR */
+#ifdef ECORE_XCB_DAMAGE
+# include <xcb/damage.h>
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_COMPOSITE
+# include <xcb/composite.h>
+#endif /* ECORE_XCB_COMPOSITE */
+#ifdef ECORE_XCB_DPMS
+# include <xcb/dpms.h>
+#endif /* ECORE_XCB_DPMS */
+#ifdef ECORE_XCB_RANDR
+# include <xcb/randr.h>
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_RENDER
+# include <xcb/render.h>
+#endif /* ECORE_XCB_RENDER */
+#ifdef ECORE_XCB_SCREENSAVER
+# include <xcb/screensaver.h>
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+# include <xcb/shape.h>
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+# include <xcb/sync.h>
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_XFIXES
+# include <xcb/xfixes.h>
+#endif /* ECORE_XCB_XFIXES */
+#ifdef ECORE_XCB_XINERAMA
+# include <xcb/xinerama.h>
+#endif /* ECORE_XCB_XINERAMA */
+#ifdef ECORE_XCB_XPRINT
+# include <xcb/xprint.h>
+#endif /* ECORE_XCB_XPRINT */
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_X.h"
+
+extern int _ecore_x11xcb_log_dom ;
+
+#ifdef ECORE_XLIB_XCB_DEFAULT_LOG_COLOR
+# undef ECORE_XLIB_XCB_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_XLIB_XCB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_x11xcb_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_x11xcb_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_x11xcb_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_x11xcb_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_x11xcb_log_dom, __VA_ARGS__)
+
+typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern;
+
+struct _Ecore_X_Selection_Intern
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom selection;
+ unsigned char *data;
+ int length;
+ Ecore_X_Time time;
+};
+
+typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter;
+
+struct _Ecore_X_Selection_Converter
+{
+ Ecore_X_Atom target;
+ int (*convert)(char *target, void *data, int size,
+ void **data_ret, int *size_ret);
+ Ecore_X_Selection_Converter *next;
+};
+
+typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser;
+
+struct _Ecore_X_Selection_Parser
+{
+ char *target;
+ void *(*parse)(const char *target, void *data, int size, int format);
+ Ecore_X_Selection_Parser *next;
+};
+
+typedef struct _Ecore_X_DND_Source
+{
+ int version;
+ Ecore_X_Window win, dest;
+
+ enum {
+ ECORE_X_DND_SOURCE_IDLE,
+ ECORE_X_DND_SOURCE_DRAGGING,
+ ECORE_X_DND_SOURCE_DROPPED,
+ ECORE_X_DND_SOURCE_CONVERTING
+ } state;
+
+ struct {
+ short x, y;
+ unsigned short width, height;
+ } rectangle;
+
+ struct {
+ Ecore_X_Window window;
+ int x, y;
+ } prev;
+
+ Ecore_X_Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+ int suppress;
+
+ int await_status;
+} Ecore_X_DND_Source;
+
+typedef struct _Ecore_X_DND_Target
+{
+ int version;
+ Ecore_X_Window win, source;
+
+ enum {
+ ECORE_X_DND_TARGET_IDLE,
+ ECORE_X_DND_TARGET_ENTERED
+ } state;
+
+ struct {
+ int x, y;
+ } pos;
+
+ Ecore_X_Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+} Ecore_X_DND_Target;
+
+extern int ECORE_X_MODIFIER_SHIFT;
+extern int ECORE_X_MODIFIER_CTRL;
+extern int ECORE_X_MODIFIER_ALT;
+extern int ECORE_X_MODIFIER_WIN;
+
+extern int ECORE_X_LOCK_SCROLL;
+extern int ECORE_X_LOCK_NUM;
+extern int ECORE_X_LOCK_CAPS;
+
+extern Ecore_X_Connection *_ecore_xcb_conn;
+extern Ecore_X_Screen *_ecore_xcb_screen;
+extern double _ecore_xcb_double_click_time;
+extern Ecore_X_Time _ecore_xcb_event_last_time;
+extern Ecore_X_Window _ecore_xcb_event_last_window;
+extern int16_t _ecore_xcb_event_last_root_x;
+extern int16_t _ecore_xcb_event_last_root_y;
+extern int _ecore_xcb_xcursor;
+
+extern Ecore_X_Atom _ecore_xcb_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
+
+extern int _ecore_window_grabs_num;
+extern Ecore_X_Window *_ecore_window_grabs;
+extern int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
+extern void *_ecore_window_grab_replay_data;
+
+extern Ecore_X_Window _ecore_xcb_private_window;
+
+
+void _ecore_x_error_handler_init(void);
+
+void _ecore_x_event_handle_any_event (xcb_generic_event_t *event);
+void _ecore_x_event_handle_key_press (xcb_generic_event_t *event);
+void _ecore_x_event_handle_key_release (xcb_generic_event_t *event);
+void _ecore_x_event_handle_button_press (xcb_generic_event_t *event);
+void _ecore_x_event_handle_button_release (xcb_generic_event_t *event);
+void _ecore_x_event_handle_motion_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_enter_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_leave_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_focus_in (xcb_generic_event_t *event);
+void _ecore_x_event_handle_focus_out (xcb_generic_event_t *event);
+void _ecore_x_event_handle_keymap_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_expose (xcb_generic_event_t *event);
+void _ecore_x_event_handle_graphics_expose (xcb_generic_event_t *event);
+void _ecore_x_event_handle_visibility_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_create_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_destroy_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_unmap_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_map_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_map_request (xcb_generic_event_t *event);
+void _ecore_x_event_handle_reparent_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_configure_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_configure_request (xcb_generic_event_t *event);
+void _ecore_x_event_handle_gravity_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_resize_request (xcb_generic_event_t *event);
+void _ecore_x_event_handle_circulate_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_circulate_request (xcb_generic_event_t *event);
+void _ecore_x_event_handle_property_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_selection_clear (xcb_generic_event_t *event);
+void _ecore_x_event_handle_selection_request (xcb_generic_event_t *event);
+void _ecore_x_event_handle_selection_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_colormap_notify (xcb_generic_event_t *event);
+void _ecore_x_event_handle_client_message (xcb_generic_event_t *event);
+void _ecore_x_event_handle_mapping_notify (xcb_generic_event_t *event);
+#ifdef ECORE_XCB_DAMAGE
+void _ecore_x_event_handle_damage_notify (xcb_generic_event_t *event);
+#endif /* ECORE_XCB_DAMAGE */
+#ifdef ECORE_XCB_RANDR
+void _ecore_x_event_handle_randr_change (xcb_generic_event_t *event);
+#endif /* ECORE_XCB_RANDR */
+#ifdef ECORE_XCB_SCREENSAVER
+void _ecore_x_event_handle_screensaver_notify (xcb_generic_event_t *event);
+#endif /* ECORE_XCB_SCREENSAVER */
+#ifdef ECORE_XCB_SHAPE
+void _ecore_x_event_handle_shape_change (xcb_generic_event_t *event);
+#endif /* ECORE_XCB_SHAPE */
+#ifdef ECORE_XCB_SYNC
+void _ecore_x_event_handle_sync_counter (xcb_generic_event_t *event);
+void _ecore_x_event_handle_sync_alarm (xcb_generic_event_t *event);
+#endif /* ECORE_XCB_SYNC */
+#ifdef ECORE_XCB_FIXES
+void _ecore_x_event_handle_fixes_selection_notify(xcb_generic_event_t *event);
+#endif /* ECORE_XCB_FIXES */
+
+
+/* requests / replies */
+int _ecore_x_reply_init ();
+void _ecore_x_reply_shutdown ();
+void _ecore_xcb_cookie_cache (unsigned int cookie);
+unsigned int _ecore_xcb_cookie_get (void);
+void _ecore_xcb_reply_cache (void *reply);
+void *_ecore_xcb_reply_get (void);
+
+
+/* atoms */
+extern Ecore_X_Atom ECORE_X_ATOM_ATOM;
+extern Ecore_X_Atom ECORE_X_ATOM_CARDINAL;
+extern Ecore_X_Atom ECORE_X_ATOM_STRING;
+extern Ecore_X_Atom ECORE_X_ATOM_WINDOW;
+extern Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE;
+extern Ecore_X_Atom ECORE_X_ATOM_WM_SIZE_HINTS;
+
+#define ECORE_X_ATOMS_COUNT 117
+
+void _ecore_x_atom_init (xcb_intern_atom_cookie_t *);
+void _ecore_x_atom_init_finalize (xcb_intern_atom_cookie_t *);
+
+
+/* damage */
+void _ecore_x_damage_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_damage_init_finalize (void);
+
+/* composite */
+void _ecore_x_composite_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_composite_init_finalize (void);
+
+/* from dnd */
+void _ecore_x_dnd_init (void);
+void _ecore_x_dnd_shutdown (void);
+Ecore_X_DND_Source *_ecore_x_dnd_source_get (void);
+Ecore_X_DND_Target *_ecore_x_dnd_target_get (void);
+void _ecore_x_dnd_drag (Ecore_X_Window root,
+ int x,
+ int y);
+
+
+/* dpms */
+void _ecore_x_dpms_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_dpms_init_finalize (void);
+
+
+/* netwm */
+Ecore_X_Window_State _ecore_x_netwm_state_get(Ecore_X_Atom a);
+int _ecore_x_netwm_startup_info_begin(Ecore_X_Window win, char *data);
+int _ecore_x_netwm_startup_info(Ecore_X_Window win, char *data);
+
+
+/* randr */
+void _ecore_x_randr_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_randr_init_finalize (void);
+
+
+/* selection */
+void _ecore_x_selection_init(void);
+void _ecore_x_selection_shutdown(void);
+Ecore_X_Atom _ecore_x_selection_target_atom_get(const char *target);
+char *_ecore_x_selection_target_get(Ecore_X_Atom target);
+Ecore_X_Selection_Intern *_ecore_x_selection_get(Ecore_X_Atom selection);
+int _ecore_x_selection_set(Ecore_X_Window w, const void *data, int len, Ecore_X_Atom selection);
+int _ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret);
+void *_ecore_x_selection_parse(const char *target, void *data, int size, int format);
+
+
+/* screensaver */
+void _ecore_x_screensaver_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_screensaver_init_finalize (void);
+
+
+/* shape */
+void _ecore_x_shape_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_shape_init_finalize (void);
+
+
+/* sync */
+void _ecore_x_sync_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_sync_init_finalize (void);
+
+
+/* xfixes */
+void _ecore_x_xfixes_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_xfixes_init_finalize (void);
+
+
+/* xinerama */
+void _ecore_x_xinerama_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_xinerama_init_finalize (void);
+
+
+/* xprint */
+void _ecore_x_xprint_init (const xcb_query_extension_reply_t *reply);
+void _ecore_x_xprint_init_finalize (void);
+
+/* to categorize */
+void _ecore_x_sync_magic_send(int val, Ecore_X_Window swin);
+void _ecore_x_window_grab_remove(Ecore_X_Window win);
+void _ecore_x_key_grab_remove(Ecore_X_Window win);
+
+
+#endif /* __ECORE_XCB_PRIVATE_H__*/
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_RandR_Group X RandR Extension Functions
+ *
+ * Functions related to the X RandR extension.
+ */
+
+
+#ifdef ECORE_XCB_RANDR
+static int _randr_available = 0;
+static xcb_randr_query_version_cookie_t _ecore_xcb_randr_init_cookie;
+#endif /* ECORE_XCB_RANDR */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_randr_init and
+ _ecore_xcb_randr_init_finalize. The first one gets the cookies and
+ the second one gets the replies and set the atoms. */
+
+void
+_ecore_x_randr_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_RANDR
+ if (reply && (reply->present))
+ _ecore_xcb_randr_init_cookie = xcb_randr_query_version_unchecked(_ecore_xcb_conn, 1, 2);
+#endif /* ECORE_XCB_RANDR */
+}
+
+void
+_ecore_x_randr_init_finalize(void)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_query_version_reply_t *reply;
+
+ reply = xcb_randr_query_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_randr_init_cookie, NULL);
+
+ if (reply)
+ {
+ if ((reply->major_version >= 1) &&
+ (reply->minor_version >= 1))
+ _randr_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_RANDR */
+}
+
+/**
+ * Return whether the X server supports the RandR Extension.
+ * @return 1 if the X RandR Extension is available, 0 otherwise.
+ *
+ * Return 1 if the X server supports the RandR Extension version 1.1,
+ * 0 otherwise.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI int
+ecore_x_randr_query(void)
+{
+#ifdef ECORE_XCB_RANDR
+ return _randr_available;
+#else
+ return 0;
+#endif /* ECORE_XCB_RANDR */
+}
+
+
+static Ecore_X_Window
+_xcb_randr_root_to_screen(Ecore_X_Window root)
+{
+ xcb_screen_iterator_t iter;
+
+ iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
+ for (; iter.rem; xcb_screen_next(&iter))
+ {
+ if (iter.data->root == root)
+ return iter.data->root;
+ }
+
+ return XCB_NONE;
+}
+
+/**
+ * Select if the ScreenChangeNotify events will be sent.
+ * @param window The window.
+ * @param on 1 to enable, 0 to disable.
+ * @return 1 on success, 0 otherwise.
+ *
+ * If @p on value is @c 1, ScreenChangeNotify events
+ * will be sent when the screen configuration changes, either from
+ * this protocol extension, or due to detected external screen
+ * configuration changes. ScreenChangeNotify may also be sent when
+ * this request executes if the screen configuration has changed since
+ * the client connected, to avoid race conditions.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI int
+ecore_x_randr_events_select(Ecore_X_Window window,
+ int on)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_select_input(_ecore_xcb_conn, window,
+ on ? XCB_RANDR_SCREEN_CHANGE_NOTIFY : 0);
+ return 1;
+#else
+ return 0;
+#endif /* ECORE_XCB_RANDR */
+}
+
+/**
+ * Sends the GetScreenInfo request.
+ * @param window Window whose properties are requested.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI void
+ecore_x_randr_get_screen_info_prefetch(Ecore_X_Window window)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_cookie_t cookie;
+
+ cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn,
+ _xcb_randr_root_to_screen(window));
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_RANDR */
+}
+
+
+/**
+ * Gets the reply of the GetScreenInfo request sent by ecore_x_randr_get_screen_info_prefetch().
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI void
+ecore_x_randr_get_screen_info_fetch(void)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_cookie_t cookie;
+ xcb_randr_get_screen_info_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply =xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_RANDR */
+}
+
+/**
+ * Get the set of rotations and reflections.
+ * @param root The window (Unused).
+ * @return The set of rotations and reflections.
+ *
+ * Get the set of rotations and reflections supported by the screen
+ * associated to @p window (passed to
+ * ecore_x_randr_get_screen_info_prefetch()).
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
+ * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI Ecore_X_Randr_Rotation
+ecore_x_randr_screen_rotations_get(Ecore_X_Window root __UNUSED__)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ return reply->rotations;
+#else
+ return 0;
+#endif /* ECORE_XCB_RANDR */
+}
+
+/**
+ * Get the rotation.
+ * @param root The window (Unused).
+ * @return The rotation.
+ *
+ * Get the rotation supported by the screen
+ * associated to @p window (passed to
+ * ecore_x_randr_get_screen_info_prefetch()).
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
+ * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI Ecore_X_Randr_Rotation
+ecore_x_randr_screen_rotation_get(Ecore_X_Window root __UNUSED__)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ return reply->rotation;
+#else
+ return 0;
+#endif /* ECORE_XCB_RANDR */
+}
+
+/**
+ * Get the frame buffer sizes.
+ * @param root The window (Unused).
+ * @param num The number of sizes.
+ * @return The sizes.
+ *
+ * Get the list of possible frame buffer sizes (at the normal
+ * orientation supported by the screen associated to @p window (passed
+ * to ecore_x_randr_get_screen_info_prefetch()). Each size indicates
+ * both the linear physical size of the screen and the pixel size.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
+ * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI Ecore_X_Screen_Size *
+ecore_x_randr_screen_sizes_get(Ecore_X_Window root __UNUSED__,
+ int *num)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_reply_t *reply;
+ xcb_randr_screen_size_t *sizes;
+ Ecore_X_Screen_Size *ret;
+ int n;
+ int i;
+
+ if (num) *num = 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return NULL;
+
+ n = xcb_randr_get_screen_info_sizes_length(reply);
+ ret = calloc(n, sizeof(Ecore_X_Screen_Size));
+ if (!ret) return NULL;
+
+ if (num) *num = n;
+ sizes = xcb_randr_get_screen_info_sizes(reply);
+ for (i = 0; i < n; i++)
+ {
+ ret[i].width = sizes[i].width;
+ ret[i].height = sizes[i].height;
+ }
+
+ return ret;
+#else
+ if (num) *num = 0;
+ return NULL;
+#endif /* ECORE_XCB_RANDR */
+}
+
+/**
+ * Get the current frame buffer size.
+ * @param root The window (Unused).
+ * @return The active size.
+ *
+ * Get the active frame buffer size supported by the screen associated
+ * to @p window (passed to
+ * ecore_x_randr_get_screen_info_prefetch()).
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
+ * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI Ecore_X_Screen_Size
+ecore_x_randr_current_screen_size_get(Ecore_X_Window root __UNUSED__)
+{
+ Ecore_X_Screen_Size ret = { -1, -1 };
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_reply_t *reply;
+ xcb_randr_screen_size_t *sizes;
+ uint16_t size_index;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return ret;
+
+ size_index = reply->sizeID;
+ sizes = xcb_randr_get_screen_info_sizes(reply);
+ if (size_index < reply->nSizes)
+ {
+ ret.width = sizes[size_index].mwidth;
+ ret.height = sizes[size_index].mheight;
+ }
+#endif /* ECORE_XCB_RANDR */
+
+ return ret;
+}
+
+/**
+ * Get the current refresh rate.
+ * @param root The window (Unused).
+ * @return The current refresh rate.
+ *
+ * Get the current refresh rate supported by the screen associated
+ * to @p window (passed to
+ * ecore_x_randr_get_screen_info_prefetch()).
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
+ * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI Ecore_X_Screen_Refresh_Rate
+ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root __UNUSED__)
+{
+ Ecore_X_Screen_Refresh_Rate ret = { -1 };
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return ret;
+
+ ret.rate = reply->rate;
+#endif /* ECORE_XCB_RANDR */
+
+ return ret;
+}
+
+/**
+ * Get the refresh rates.
+ * @param root The window (Unused).
+ * @param num The number of refresh rates.
+ * @return The refresh rates.
+ *
+ * Get the list of refresh rates for each size supported by the screen
+ * associated to @p window (passed to
+ * ecore_x_randr_get_screen_info_prefetch()). Each element
+ * of 'sizes' has a corresponding element in 'refresh'. An empty list
+ * indicates no known rates, or a device for which refresh is not
+ * relevant.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_randr_get_screen_info_prefetch(), which sends the GetScreenInfo request,
+ * then ecore_x_randr_get_screen_info_fetch(), which gets the reply.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI Ecore_X_Screen_Refresh_Rate *
+ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root __UNUSED__,
+ int size_id __UNUSED__,
+ int *num)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_get_screen_info_reply_t *reply;
+ Ecore_X_Screen_Refresh_Rate *ret;
+ Ecore_X_Screen_Refresh_Rate *tmp;
+ xcb_randr_refresh_rates_iterator_t iter;
+ uint16_t n;
+
+ if (num) *num = 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return NULL;
+
+ n = reply->nSizes;
+ ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
+ if (!ret)
+ return NULL;
+
+ if (num) *num = n;
+
+ /* FIXME: maybe there's a missing function in xcb randr implementation */
+ iter = xcb_randr_get_screen_info_rates_iterator(reply);
+ tmp = ret;
+ for (; iter.rem; xcb_randr_refresh_rates_next(&iter), tmp++)
+ {
+ tmp->rate = iter.data->nRates;;
+ }
+
+ return ret;
+#else
+ if (num) *num = 0;
+ return NULL;
+#endif /* ECORE_XCB_RANDR */
+}
+
+/* FIXME: round trip. Should we remove it ? */
+
+/**
+ * Set the screen rotation.
+ * @param root The root window.
+ * @param rot The rotation.
+ *
+ * Set the rotation of the screen associated to @p root.
+ *
+ * Note that that function is blocking.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI void
+ecore_x_randr_screen_rotation_set(Ecore_X_Window root,
+ Ecore_X_Randr_Rotation rot)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_set_screen_config_cookie_t cookie;
+ xcb_randr_set_screen_config_reply_t *reply_config;
+ xcb_randr_get_screen_info_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return;
+
+ cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
+ XCB_CURRENT_TIME,
+ reply->config_timestamp,
+ reply->sizeID,
+ rot,
+ 0);
+ reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply_config)
+ free(reply_config);
+#endif /* ECORE_XCB_RANDR */
+}
+
+/* FIXME: round trip. Should we remove it ? */
+
+/**
+ * Set the screen size.
+ * @param root The root window.
+ * @param size The size.
+ *
+ * Set the size of the screen associated to @p root.
+ *
+ * Note that that function is blocking.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI int
+ecore_x_randr_screen_size_set(Ecore_X_Window root,
+ Ecore_X_Screen_Size size)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_set_screen_config_cookie_t cookie;
+ xcb_randr_set_screen_config_reply_t *reply_config;
+ xcb_randr_get_screen_info_reply_t *reply;
+ xcb_randr_screen_size_iterator_t iter;
+ int size_index = -1;
+ int i;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ iter = xcb_randr_get_screen_info_sizes_iterator(reply);
+ for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
+ {
+ if ((iter.data->width = size.width) &&
+ (iter.data->height = size.height) &&
+ (iter.data->mwidth = size.width) &&
+ (iter.data->mheight = size.height))
+ {
+ size_index = i;
+ break;
+ }
+ }
+ if (size_index == -1) return 0;
+
+ cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
+ XCB_CURRENT_TIME,
+ reply->config_timestamp,
+ size_index,
+ XCB_RANDR_ROTATION_ROTATE_0,
+ 0);
+ reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply_config)
+ return 0;
+
+ free(reply_config);
+
+ return 1;
+#else
+ return 0;
+#endif /* ECORE_XCB_RANDR */
+}
+
+/* FIXME: round trip. Should we remove it ? */
+
+/**
+ * Set the screen refresh rate.
+ * @param root The root window.
+ * @param size The size.
+ * @param rate The refresh rate.
+ *
+ * Set the size and the refresh rate of the screen associated to
+ * @p root.
+ *
+ * Note that that function is blocking.
+ * @ingroup Ecore_X_RandR_Group
+ */
+EAPI int
+ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root,
+ Ecore_X_Screen_Size size,
+ Ecore_X_Screen_Refresh_Rate rate)
+{
+#ifdef ECORE_XCB_RANDR
+ xcb_randr_set_screen_config_cookie_t cookie;
+ xcb_randr_set_screen_config_reply_t *reply_config;
+ xcb_randr_get_screen_info_reply_t *reply;
+ xcb_randr_screen_size_iterator_t iter;
+ int size_index = -1;
+ int i;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ iter = xcb_randr_get_screen_info_sizes_iterator(reply);
+ for (i = 0; iter.rem; xcb_randr_screen_size_next(&iter), i++)
+ {
+ if ((iter.data->width = size.width) &&
+ (iter.data->height = size.height) &&
+ (iter.data->mwidth = size.width) &&
+ (iter.data->mheight = size.height))
+ {
+ size_index = i;
+ break;
+ }
+ }
+ if (size_index == -1) return 0;
+
+ cookie = xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
+ XCB_CURRENT_TIME,
+ reply->config_timestamp,
+ size_index,
+ XCB_RANDR_ROTATION_ROTATE_0,
+ rate.rate);
+ reply_config = xcb_randr_set_screen_config_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply_config)
+ return 0;
+
+ free(reply_config);
+
+ return 1;
+#else
+ return 0;
+#endif /* ECORE_XCB_RANDR */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+
+
+/*
+ * [x] XCreateRegion
+ * [ ] XPolygonRegion
+ * [x] XSetRegion
+ * [x] XDestroyRegion
+ *
+ * [x] XOffsetRegion
+ * [ ] XShrinkRegion
+ *
+ * [ ] XClipBox
+ * [x] XIntersectRegion
+ * [x] XUnionRegion
+ * [x] XUnionRectWithRegion
+ * [x] XSubtractRegion
+ * [ ] XXorRegion
+ *
+ * [x] XEmptyRegion
+ * [x] XEqualRegion
+ *
+ * [x] XPointInRegion
+ * [x] XRectInRegion
+ */
+
+EAPI Ecore_X_XRegion *
+ecore_x_xregion_new()
+{
+ pixman_region16_t *region;
+
+ region = (pixman_region16_t *)malloc (sizeof (pixman_region16_t));
+ if (!region)
+ return NULL;
+
+ pixman_region_init(region);
+
+ return (Ecore_X_XRegion *)region;
+}
+
+EAPI void
+ecore_x_xregion_free(Ecore_X_XRegion *region)
+{
+ if (!region)
+ return;
+
+ pixman_region_fini(region);
+ free(region);
+}
+
+EAPI int
+ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc)
+{
+ xcb_rectangle_t *rects;
+ pixman_box16_t *boxes;
+ int num;
+
+ if (!region)
+ return 0;
+
+ boxes = pixman_region_rectangles ((pixman_region16_t *)region, &num);
+
+ if (!boxes || (num == 0))
+ return 0;
+
+ rects = (xcb_rectangle_t *)malloc(sizeof(xcb_rectangle_t) * num);
+ if (!rects)
+ return 0;
+
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = boxes[i].x1;
+ rects[i].y = boxes[i].y1;
+ rects[i].width = boxes[i].x2 - boxes[i].x1 + 1;
+ rects[i].height = boxes[i].y2 - boxes[i].y1 + 1;
+ }
+
+ xcb_set_clip_rectangles(_ecore_x_connection,
+ XCB_CLIP_ORDERING_YX_BANDED,
+ gc,
+ 0, 0,
+ num,
+ rects);
+ return 1;
+}
+
+EAPI void
+ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y)
+{
+ if (!region)
+ return;
+
+ pixman_region_translate((pixman_region16_t *)region, x, y);
+}
+
+EAPI int
+ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2)
+{
+ return pixman_region_intersect((pixman_region16_t *)dst, (pixman_region16_t *)r1, (pixman_region16_t *)r2);
+}
+
+EAPI int
+ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2)
+{
+ return pixman_region_union((pixman_region16_t *)dst, (pixman_region16_t *)r1, (pixman_region16_t *)r2);
+}
+
+EAPI int
+ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect)
+{
+ return pixman_region_union_rect((pixman_region16_t *)dst, (pixman_region16_t *)src,
+ rect->x, rect->y, rect->width, rect->height);
+}
+
+EAPI int
+ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2)
+{
+ return pixman_region_subtract((pixman_region16_t *)dst, (pixman_region16_t *)rm, (pixman_region16_t *)rs);
+}
+
+EAPI int
+ecore_x_xregion_is_empty(Ecore_X_XRegion *region)
+{
+ if (!region)
+ return 1;
+
+ return !pixman_region_not_empty((pixman_region16_t *)region);
+}
+
+EAPI int
+ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2)
+{
+ if (!r1 || !r2)
+ return 0;
+
+ return pixman_region_equal((pixman_region16_t *)r1, (pixman_region16_t *)r2);
+}
+
+EAPI int
+ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y)
+{
+ if (!region)
+ return 0;
+
+ return pixman_region_contains_point((pixman_region16_t *)region, x, y);
+}
+
+EAPI int
+ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect)
+{
+ pixman_box16_t box;
+
+ if (!region || !rect)
+ return 0;
+
+ box.x1 = rect->x;
+ box.y1 = rect->y;
+ box.x2 = rect->x + rect->width - 1;
+ box.y2 = rect->y + rect->height - 1;
+
+ return pixman_region_contains_rectangle((pixman_region16_t *)region, &box);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include <stdlib.h>
+
+
+/*
+ * FIXME:
+ * - in ecore_xcb_cookie_cache, should provide better error management
+ * when memory allocation fails
+ * - Use an array instead of a list
+ * - Is ecore_xcb_reply_free really needed ?
+ * _ecore_xcb_reply_cache frees the current reply and
+ * _ecore_x_reply_shutdown frees the last reply to free.
+ * I keep it in case it is need for memory improvements,
+ * but its code is commented.
+ */
+
+static Eina_List *_ecore_xcb_cookies = NULL;
+static void *_ecore_xcb_reply = NULL;
+
+typedef struct _Ecore_Xcb_Data Ecore_Xcb_Data;
+
+struct _Ecore_Xcb_Data
+{
+ unsigned int cookie;
+};
+
+
+int
+_ecore_x_reply_init ()
+{
+ return 1;
+}
+
+void
+_ecore_x_reply_shutdown ()
+{
+ Ecore_Xcb_Data *data;
+
+ if (_ecore_xcb_reply)
+ free(_ecore_xcb_reply);
+
+ if (!_ecore_xcb_cookies)
+ return;
+
+ EINA_LIST_FREE(_ecore_xcb_cookies, data)
+ free(data);
+}
+
+void
+_ecore_xcb_cookie_cache (unsigned int cookie)
+{
+ Ecore_Xcb_Data *data;
+
+ if (!_ecore_xcb_cookies)
+ return;
+
+ data = (Ecore_Xcb_Data *)malloc(sizeof(Ecore_Xcb_Data));
+ if (!data)
+ return;
+
+ data->cookie = cookie;
+
+ _ecore_xcb_cookies = eina_list_append(_ecore_xcb_cookies, data);
+ if (!eina_list_data_find(_ecore_xcb_cookies, data))
+ {
+ free(data);
+ return;
+ }
+}
+
+unsigned int
+_ecore_xcb_cookie_get (void)
+{
+ Ecore_Xcb_Data *data;
+ unsigned int cookie;
+
+ if (!_ecore_xcb_cookies)
+ return 0;
+
+ data = eina_list_data_get(_ecore_xcb_cookies);
+ if (!data) return 0;
+
+ _ecore_xcb_cookies = eina_list_remove_list(_ecore_xcb_cookies, _ecore_xcb_cookies);
+ cookie = data->cookie;
+ free(data);
+
+ return cookie;
+}
+
+void
+_ecore_xcb_reply_cache (void *reply)
+{
+ if (_ecore_xcb_reply)
+ free(_ecore_xcb_reply);
+ _ecore_xcb_reply = reply;
+}
+
+void *
+_ecore_xcb_reply_get (void)
+{
+ return _ecore_xcb_reply;
+}
+
+EAPI void
+ecore_xcb_reply_free()
+{
+/* if (_ecore_xcb_reply) */
+/* { */
+/* free(_ecore_xcb_reply); */
+/* _ecore_xcb_reply = NULL; */
+/* } */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_ScreenSaver_Group X ScreenSaver extension
+ *
+ * These functions use the ScreenSaver extension of the X server
+ */
+
+
+#ifdef ECORE_XCB_SCREENSAVER
+static int _screensaver_available = 0;
+static xcb_screensaver_query_version_cookie_t _ecore_xcb_screensaver_init_cookie;
+#endif /* ECORE_XCB_SCREENSAVER */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_screensaver_init and
+ _ecore_xcb_screensaver_init_finalize. The first one gets the cookies and
+ the second one gets the replies and set the atoms. */
+
+void
+_ecore_x_screensaver_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ if (reply && (reply->present))
+ _ecore_xcb_screensaver_init_cookie = xcb_screensaver_query_version_unchecked(_ecore_xcb_conn, 1, 1);
+#endif /* ECORE_XCB_SCREENSAVER */
+}
+
+void
+_ecore_x_screensaver_init_finalize(void)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_screensaver_query_version_reply_t *reply;
+
+ reply = xcb_screensaver_query_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_screensaver_init_cookie, NULL);
+
+ if (reply)
+ {
+ if ((reply->server_major_version >= 1) &&
+ (reply->server_minor_version >= 1))
+ _screensaver_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_SCREENSAVER */
+}
+
+
+/**
+ * Return whether the X server supports the ScreenSaver Extension.
+ * @return 1 if the X ScreenSaver Extension is available, 0 otherwise.
+ *
+ * Return 1 if the X server supports the ScreenSaver Extension version 1.0,
+ * 0 otherwise.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI int
+ecore_x_screensaver_event_available_get(void)
+{
+ return 1;
+}
+
+
+/**
+ * Sends the QueryInfo request.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_idle_time_prefetch(void)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_screensaver_query_info_cookie_t cookie;
+
+ cookie = xcb_screensaver_query_info_unchecked(_ecore_xcb_conn, ((xcb_screen_t *)_ecore_xcb_screen)->root);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_SCREENSAVER */
+}
+
+
+/**
+ * Gets the reply of the QueryInfo request sent by ecore_x_get_screensaver_prefetch().
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_idle_time_fetch(void)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_screensaver_query_info_cookie_t cookie;
+ xcb_screensaver_query_info_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_screensaver_query_info_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_SCREENSAVER */
+}
+
+
+/**
+ * Get the number of seconds since the last input was received.
+ * @return The number of seconds.
+ *
+ * Get the number of milliseconds since the last input was received
+ * from the user on any of the input devices.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI int
+ecore_x_screensaver_idle_time_get(void)
+{
+ int idle = 0;
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_screensaver_query_info_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+
+ if (!reply) return 0;
+
+ /* FIXME: check if it is ms_since_user_input or ms_until_server */
+ idle = reply->ms_since_user_input / 1000;
+#endif /* ECORE_XCB_SCREENSAVER */
+
+ return idle;
+}
+
+
+/**
+ * Set the parameters of the screen saver.
+ * @param timeout The timeout, in second.
+ * @param interval The interval, in seconds.
+ * @param blank 0 to disable screen blanking, otherwise enable it.
+ * @param expose Allow Expose generation event or not.
+ *
+ * Set the parameters of the screen saver. @p timeout is the timeout,
+ * in seconds, until the screen saver turns on. @p interval is the
+ * interval, in seconds, between screen saver alterations. @p blank
+ * specifies how to enable screen blanking. @p expose specifies the
+ * screen save control values.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_set(int timeout,
+ int interval,
+ int blank,
+ int expose)
+{
+ xcb_set_screen_saver(_ecore_xcb_conn,
+ (int16_t)timeout,
+ (int16_t)interval,
+ (uint8_t)blank,
+ (uint8_t)expose);
+}
+
+
+/**
+ * Sends the GetScreenSaver request.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_get_screensaver_prefetch(void)
+{
+ xcb_get_screen_saver_cookie_t cookie;
+
+ cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetScreenSaver request sent by ecore_x_get_screensaver_prefetch().
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_get_screensaver_fetch(void)
+{
+ xcb_get_screen_saver_cookie_t cookie;
+ xcb_get_screen_saver_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+
+/**
+ * Set the timeout of the screen saver.
+ * @param timeout The timeout to set.
+ *
+ * Set the @p timeout, in seconds, until the screen saver turns on.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_timeout_set(int timeout)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ xcb_set_screen_saver(_ecore_xcb_conn,
+ (int16_t)timeout,
+ reply->interval,
+ reply->prefer_blanking,
+ reply->allow_exposures);
+}
+
+
+/**
+ * Get the timeout of the screen saver.
+ * @return The timeout.
+ *
+ * Get the @p timeout, in seconds, until the screen saver turns on.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI int
+ecore_x_screensaver_timeout_get(void)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0.0;
+
+ return (int)reply->timeout;
+}
+
+
+/**
+ * Set the interval of the screen saver.
+ * @param interval The interval to set.
+ *
+ * Set the @p interval, in seconds, between screen saver alterations.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_interval_set(int interval)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ xcb_set_screen_saver(_ecore_xcb_conn,
+ reply->timeout,
+ (int16_t)interval,
+ reply->prefer_blanking,
+ reply->allow_exposures);
+}
+
+
+/**
+ * Get the interval of the screen saver.
+ * @return The interval.
+ *
+ * Get the @p interval, in seconds, between screen saver alterations.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI int
+ecore_x_screensaver_interval_get(void)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0.0;
+
+ return (int)reply->interval;
+}
+
+
+/**
+ * Set the screen blanking.
+ * @param blank The blank to set.
+ *
+ * @p blank specifies how to enable screen blanking.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_blank_set(int blank)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ xcb_set_screen_saver(_ecore_xcb_conn,
+ reply->timeout,
+ reply->interval,
+ (uint8_t)blank,
+ reply->allow_exposures);
+}
+
+
+/**
+ * Get the screen blanking.
+ * @return The blanking.
+ *
+ * Get the screen blanking.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI int
+ecore_x_screensaver_blank_get(void)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0.0;
+
+ return (int)reply->prefer_blanking;
+}
+
+
+/**
+ * Set the screen save control values.
+ * @param expose The expose to set.
+ *
+ * Set the screen save control values.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_expose_set(int expose)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return;
+
+ xcb_set_screen_saver(_ecore_xcb_conn,
+ reply->timeout,
+ reply->interval,
+ reply->prefer_blanking,
+ (uint8_t)expose);
+}
+
+
+/**
+ * Get the screen save control values.
+ * @return The expose.
+ *
+ * Get the screen save control values.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_screensaver_prefetch(), which sends the GetScreenSaver request,
+ * then ecore_x_get_screensaver_fetch(), which gets the reply.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI int
+ecore_x_screensaver_expose_get(void)
+{
+ xcb_get_screen_saver_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0.0;
+
+ return (int)reply->allow_exposures;
+}
+
+
+/**
+ * Specifies if the Screen Saver NotifyMask event should be generated.
+ * @param on 0 to disable the generation of the event, otherwise enable it.
+ *
+ * Specifies if the Screen Saver NotifyMask event on the screen
+ * associated with drawable should be generated for this client. If
+ * @p on is set to @c 0, the generation is disabled, otherwise, it is
+ * enabled.
+ * @ingroup Ecore_X_ScreenSaver_Group
+ */
+EAPI void
+ecore_x_screensaver_event_listen_set(int on)
+{
+#ifdef ECORE_XCB_SCREENSAVER
+ xcb_screensaver_select_input(_ecore_xcb_conn,
+ ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ on ? XCB_SCREENSAVER_EVENT_NOTIFY_MASK : 0);
+#endif /* ECORE_XCB_SCREENSAVER */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include <string.h>
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+static Ecore_X_Selection_Intern selections[4];
+static Ecore_X_Selection_Converter *converters = NULL;
+static Ecore_X_Selection_Parser *parsers = NULL;
+
+static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret);
+static int _ecore_x_selection_data_default_free(void *data);
+static void *_ecore_x_selection_parser_files(const char *target, void *data, int size, int format);
+static int _ecore_x_selection_data_files_free(void *data);
+static void *_ecore_x_selection_parser_text(const char *target, void *data, int size, int format);
+static int _ecore_x_selection_data_text_free(void *data);
+static void *_ecore_x_selection_parser_targets(const char *target, void *data, int size, int format);
+static int _ecore_x_selection_data_targets_free(void *data);
+
+#define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
+
+void
+_ecore_x_selection_init(void)
+{
+ /* Initialize global data */
+ memset(selections, 0, sizeof(selections));
+
+ /* Initialize converters */
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT,
+ _ecore_x_selection_converter_text);
+#ifdef X_HAVE_UTF8_STRING
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING,
+ _ecore_x_selection_converter_text);
+#endif
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT,
+ _ecore_x_selection_converter_text);
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING,
+ _ecore_x_selection_converter_text);
+
+ /* Initialize parsers */
+ ecore_x_selection_parser_add("text/plain",
+ _ecore_x_selection_parser_text);
+ ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING,
+ _ecore_x_selection_parser_text);
+ ecore_x_selection_parser_add("text/uri-list",
+ _ecore_x_selection_parser_files);
+ ecore_x_selection_parser_add("_NETSCAPE_URL",
+ _ecore_x_selection_parser_files);
+ ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS,
+ _ecore_x_selection_parser_targets);
+}
+
+void
+_ecore_x_selection_shutdown(void)
+{
+ Ecore_X_Selection_Converter *cnv;
+ Ecore_X_Selection_Parser *prs;
+
+ /* free the selection converters */
+ cnv = converters;
+ while (cnv)
+ {
+ Ecore_X_Selection_Converter *tmp;
+
+ tmp = cnv->next;
+ free(cnv);
+ cnv = tmp;
+ }
+ converters = NULL;
+
+ /* free the selection parsers */
+ prs = parsers;
+ while (prs)
+ {
+ Ecore_X_Selection_Parser *tmp;
+
+ tmp = prs;
+ prs = prs->next;
+ free(tmp->target);
+ free(tmp);
+ }
+ parsers = NULL;
+}
+
+Ecore_X_Selection_Intern *
+_ecore_x_selection_get(Ecore_X_Atom selection)
+{
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ return &selections[0];
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ return &selections[1];
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ return &selections[2];
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ return &selections[3];
+ else
+ return NULL;
+}
+
+
+/*
+ * Sends the GetSelectionOwner request.
+ */
+void
+_ecore_xcb_get_selection_owner_prefetch(Ecore_X_Atom selection)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+
+ cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, selection);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/*
+ * Gets the reply of the GetSelectionOwner request sent by _ecore_xcb_get_selection_owner_prefetch().
+ */
+void
+_ecore_xcb_get_selection_owner_fetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+ xcb_get_selection_owner_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/*
+ * To use this function, you must call before, and in order,
+ * _ecore_xcb_get_selection_owner_prefetch(), which sends the GetSelectionOwner request,
+ * then _ecore_xcb_get_selection_owner_fetch(), which gets the reply.
+ */
+int
+_ecore_x_selection_set(Ecore_X_Window window,
+ const void *data,
+ int size,
+ Ecore_X_Atom selection)
+{
+ xcb_get_selection_owner_reply_t *reply;
+ unsigned char *buf = NULL;
+ int in;
+
+ xcb_set_selection_owner(_ecore_xcb_conn, window, selection, _ecore_xcb_event_last_time);
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply || (reply->owner != window)) return 0;
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ in = 0;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ in = 1;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ in = 2;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ in = 3;
+ else
+ return 0;
+
+ if (data)
+ {
+ selections[in].win = window;
+ selections[in].selection = selection;
+ selections[in].length = size;
+ selections[in].time = _ecore_xcb_event_last_time;
+
+ buf = malloc(size);
+ memcpy(buf, data, size);
+ selections[in].data = buf;
+ }
+ else
+ {
+ if (selections[in].data)
+ {
+ free(selections[in].data);
+ memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data));
+ }
+ }
+
+ return 1;
+}
+
+
+/**
+ * Sends the GetSelectionOwner request.
+ */
+EAPI void
+ecore_x_selection_primary_prefetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+
+ cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_PRIMARY);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_primary_prefetch().
+ */
+EAPI void
+ecore_x_selection_primary_fetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+ xcb_get_selection_owner_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Claim ownership of the PRIMARY selection and set its data.
+ * @param window The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_primary_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_primary_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_primary_set(Ecore_X_Window window,
+ const void *data,
+ int size)
+{
+ return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+/**
+ * Release ownership of the primary selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_primary_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_primary_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_primary_clear(void)
+{
+ return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+
+/**
+ * Sends the GetSelectionOwner request.
+ */
+EAPI void
+ecore_x_selection_secondary_prefetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+
+ cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_SECONDARY);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_secondary_prefetch().
+ */
+EAPI void
+ecore_x_selection_secondary_fetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+ xcb_get_selection_owner_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+
+/**
+ * Claim ownership of the SECONDARY selection and set its data.
+ * @param window The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_secondary_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_secondary_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_secondary_set(Ecore_X_Window window,
+ const void *data,
+ int size)
+{
+ return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+/**
+ * Release ownership of the secondary selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_secondary_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_secondary_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_secondary_clear(void)
+{
+ return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+
+/**
+ * Sends the GetSelectionOwner request.
+ */
+EAPI void
+ecore_x_selection_xdnd_prefetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+
+ cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_XDND);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_xdnd_prefetch().
+ */
+EAPI void
+ecore_x_selection_xdnd_fetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+ xcb_get_selection_owner_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Claim ownership of the XDND selection and set its data.
+ * @param window The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_xdnd_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_xdnd_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_xdnd_set(Ecore_X_Window window,
+ const void *data,
+ int size)
+{
+ return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_XDND);
+}
+
+/**
+ * Release ownership of the XDND selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_xdnd_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_xdnd_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_xdnd_clear(void)
+{
+ return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_XDND);
+}
+
+
+/**
+ * Sends the GetSelectionOwner request.
+ */
+EAPI void
+ecore_x_selection_clipboard_prefetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+
+ cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_CLIPBOARD);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_clipboard_prefetch().
+ */
+EAPI void
+ecore_x_selection_clipboard_fetch(void)
+{
+ xcb_get_selection_owner_cookie_t cookie;
+ xcb_get_selection_owner_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Claim ownership of the CLIPBOARD selection and set its data.
+ * @param window The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ *
+ * Get the converted data from a previous CLIPBOARD selection
+ * request. The buffer must be freed when done with.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_clipboard_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_clipboard_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_clipboard_set(Ecore_X_Window window,
+ const void *data,
+ int size)
+{
+ return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+/**
+ * Release ownership of the clipboard selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_selection_clipboard_prefetch(), which sends the GetSelectionOwner request,
+ * then ecore_x_selection_clipboard_fetch(), which gets the reply.
+ */
+EAPI int
+ecore_x_selection_clipboard_clear(void)
+{
+ return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+
+/* FIXME: roundtrip if target is not handled in the tests */
+Ecore_X_Atom
+_ecore_x_selection_target_atom_get(const char *target)
+{
+ Ecore_X_Atom x_target = XCB_NONE;
+
+ if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
+ x_target = ECORE_X_ATOM_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
+ x_target = ECORE_X_ATOM_COMPOUND_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
+ x_target = ECORE_X_ATOM_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
+ x_target = ECORE_X_ATOM_UTF8_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME))
+ x_target = ECORE_X_ATOM_FILE_NAME;
+ else
+ {
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t *reply;
+
+ cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0,
+ strlen(target), target);
+ reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ return XCB_NONE;
+ x_target = reply->atom;
+ free(reply);
+ }
+
+ return x_target;
+}
+
+
+/* FIXME: roundtrip if target is not handled in the tests */
+char *
+_ecore_x_selection_target_get(Ecore_X_Atom target)
+{
+ if (target == ECORE_X_ATOM_FILE_NAME)
+ return strdup(ECORE_X_SELECTION_TARGET_FILENAME);
+ else if (target == ECORE_X_ATOM_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_STRING);
+ else if (target == ECORE_X_ATOM_UTF8_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING);
+ else if (target == ECORE_X_ATOM_TEXT)
+ return strdup(ECORE_X_SELECTION_TARGET_TEXT);
+ else
+ {
+ xcb_get_atom_name_cookie_t cookie;
+ xcb_get_atom_name_reply_t *reply;
+ char *name;
+
+ cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, target);
+ reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!reply)
+ return NULL;
+ name = (char *)malloc(sizeof(char) * (reply->length + 1));
+ if (!name)
+ {
+ free(reply);
+ return NULL;
+ }
+ memcpy(name, xcb_get_atom_name_name(reply), reply->length);
+ name[reply->length] = '\0';
+ free(reply);
+ return name;
+ }
+}
+
+static void
+_ecore_x_selection_request(Ecore_X_Window window,
+ Ecore_X_Atom selection,
+ const char *target_str)
+{
+ Ecore_X_Atom target, prop;
+
+ target = _ecore_x_selection_target_atom_get(target_str);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
+ else
+ return;
+
+ xcb_convert_selection(_ecore_xcb_conn, window,
+ selection, target, prop,
+ XCB_CURRENT_TIME);
+}
+
+EAPI void
+ecore_x_selection_primary_request(Ecore_X_Window window,
+ const char *target)
+{
+ _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_PRIMARY, target);
+}
+
+EAPI void
+ecore_x_selection_secondary_request(Ecore_X_Window window,
+ const char *target)
+{
+ _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_SECONDARY, target);
+}
+
+EAPI void
+ecore_x_selection_xdnd_request(Ecore_X_Window window,
+ const char *target)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_DND_Target *_target;
+
+ _target = _ecore_x_dnd_target_get();
+ atom = _ecore_x_selection_target_atom_get(target);
+ xcb_convert_selection(_ecore_xcb_conn, window,
+ ECORE_X_ATOM_SELECTION_XDND, atom,
+ ECORE_X_ATOM_SELECTION_PROP_XDND,
+ _target->time);
+}
+
+EAPI void
+ecore_x_selection_clipboard_request(Ecore_X_Window window, const char *target)
+{
+ _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_CLIPBOARD, target);
+}
+
+EAPI void
+ecore_x_selection_converter_atom_add(Ecore_X_Atom target,
+ int (*func)(char *target,
+ void *data,
+ int size,
+ void **data_ret,
+ int *size_ret))
+{
+ Ecore_X_Selection_Converter *cnv;
+
+ cnv = converters;
+ if (converters)
+ {
+ while (1)
+ {
+ if (cnv->target == target)
+ {
+ cnv->convert = func;
+ return;
+ }
+ if (cnv->next)
+ cnv = cnv->next;
+ else
+ break;
+ }
+
+ cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ cnv = cnv->next;
+ }
+ else
+ {
+ converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ cnv = converters;
+ }
+ cnv->target = target;
+ cnv->convert = func;
+}
+
+EAPI void
+ecore_x_selection_converter_add(char *target,
+ int (*func)(char *target,
+ void *data,
+ int size,
+ void **data_ret,
+ int *size_ret))
+{
+ Ecore_X_Atom x_target;
+
+ if (!func || !target)
+ return;
+
+ x_target = _ecore_x_selection_target_atom_get(target);
+
+ ecore_x_selection_converter_atom_add(x_target, func);
+}
+
+EAPI void
+ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
+{
+ Ecore_X_Selection_Converter *cnv, *prev_cnv;
+
+ prev_cnv = NULL;
+ cnv = converters;
+
+ while (cnv)
+ {
+ if (cnv->target == target)
+ {
+ if (prev_cnv)
+ prev_cnv->next = cnv->next;
+ else
+ converters = cnv->next; /* This was the first converter */
+ free(cnv);
+
+ return;
+ }
+ prev_cnv = cnv;
+ cnv = cnv->next;
+ }
+}
+
+EAPI void
+ecore_x_selection_converter_del(char *target)
+{
+ Ecore_X_Atom x_target;
+
+ if (!target)
+ return;
+
+ x_target = _ecore_x_selection_target_atom_get(target);
+ ecore_x_selection_converter_atom_del(x_target);
+}
+
+EAPI int
+ecore_x_selection_notify_send(Ecore_X_Window requestor,
+ Ecore_X_Atom selection,
+ Ecore_X_Atom target,
+ Ecore_X_Atom property,
+ Ecore_X_Time time)
+{
+ xcb_selection_notify_event_t ev;
+
+ ev.time = time;
+ ev.requestor = requestor;
+ ev.selection = selection;
+ ev.target = target;
+ ev.property = property;
+ /* send_event is bit 7 (0x80) of response_type */
+ ev.response_type = 0x80;
+
+ xcb_send_event(_ecore_xcb_conn, 0,
+ requestor, 0, (const char *)&ev);
+ return 1;
+}
+
+/* Locate and run conversion callback for specified selection target */
+EAPI int
+ecore_x_selection_convert(Ecore_X_Atom selection,
+ Ecore_X_Atom target,
+ void **data_ret)
+{
+ Ecore_X_Selection_Intern *sel;
+ Ecore_X_Selection_Converter *cnv;
+ void *data;
+ char *tgt_str;
+ int size;
+
+ sel = _ecore_x_selection_get(selection);
+ tgt_str = _ecore_x_selection_target_get(target);
+
+ for (cnv = converters; cnv; cnv = cnv->next)
+ {
+ if (cnv->target == target)
+ {
+ int r;
+ r = cnv->convert(tgt_str, sel->data, sel->length, &data, &size);
+ free(tgt_str);
+ if (r)
+ {
+ *data_ret = data;
+ return r;
+ }
+ else
+ return 0;
+ }
+ }
+
+ /* Default, just return the data */
+ *data_ret = malloc(sel->length);
+ memcpy(*data_ret, sel->data, sel->length);
+ free(tgt_str);
+ return 1;
+}
+
+/* TODO: We need to work out a mechanism for automatic conversion to any requested
+ * locale using Ecore_Txt functions */
+/* Converter for standard non-utf8 text targets */
+static int
+_ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret)
+{
+
+ /* FIXME: to do... */
+
+/* XTextProperty text_prop; */
+/* char *mystr; */
+/* XICCEncodingStyle style; */
+
+/* if (!data || !size) */
+/* return 0; */
+
+/* if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) */
+/* style = XTextStyle; */
+/* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) */
+/* style = XCompoundTextStyle; */
+/* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) */
+/* style = XStringStyle; */
+/* #ifdef X_HAVE_UTF8_STRING */
+/* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) */
+/* style = XUTF8StringStyle; */
+/* #endif */
+/* else */
+/* return 0; */
+
+/* if (!(mystr = strdup(data))) */
+/* return 0; */
+
+/* #ifdef X_HAVE_UTF8_STRING */
+/* if (Xutf8TextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) */
+/* { */
+/* int bufsize = strlen((char *)text_prop.value) + 1; */
+/* *data_ret = malloc(bufsize); */
+/* memcpy(*data_ret, text_prop.value, bufsize); */
+/* *size_ret = bufsize; */
+/* XFree(text_prop.value); */
+/* free(mystr); */
+/* return 1; */
+/* } */
+/* #else */
+/* if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) */
+/* { */
+/* int bufsize = strlen(text_prop.value) + 1; */
+/* *data_ret = malloc(bufsize); */
+/* memcpy(*data_ret, text_prop.value, bufsize); */
+/* *size_ret = bufsize; */
+/* XFree(text_prop.value); */
+/* free(mystr); */
+/* return 1; */
+/* } */
+/* #endif */
+/* else */
+/* { */
+/* free(mystr); */
+/* return 0; */
+/* } */
+
+ return 0;
+}
+
+EAPI void
+ecore_x_selection_parser_add(const char *target,
+ void *(*func)(const char *target,
+ void *data,
+ int size,
+ int format))
+{
+ Ecore_X_Selection_Parser *prs;
+
+ if (!target)
+ return;
+
+ prs = parsers;
+ if (parsers)
+ {
+ while (prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ prs->parse = func;
+ return;
+ }
+ prs = prs->next;
+ }
+
+ prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ prs = prs->next;
+ }
+ else
+ {
+ parsers = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ prs = parsers;
+ }
+ prs->target = strdup(target);
+ prs->parse = func;
+}
+
+EAPI void
+ecore_x_selection_parser_del(const char *target)
+{
+ Ecore_X_Selection_Parser *prs, *prev_prs;
+
+ if (!target)
+ return;
+
+ prev_prs = NULL;
+ prs = parsers;
+
+ while (prs)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ if (prev_prs)
+ prev_prs->next = prs->next;
+ else
+ parsers = prs->next; /* This was the first parser */
+ free(prs->target);
+ free(prs);
+
+ return;
+ }
+ prev_prs = prs;
+ prs = prs->next;
+ }
+}
+
+/* Locate and run conversion callback for specified selection target */
+void *
+_ecore_x_selection_parse(const char *target, void *data, int size, int format)
+{
+ Ecore_X_Selection_Parser *prs;
+ Ecore_X_Selection_Data *sel;
+
+ for (prs = parsers; prs; prs = prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ sel = prs->parse(target, data, size, format);
+ return sel;
+ }
+ }
+
+ /* Default, just return the data */
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data));
+ sel->free = _ecore_x_selection_data_default_free;
+ sel->length = size;
+ sel->format = format;
+ sel->data = data;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_default_free(void *data)
+{
+ Ecore_X_Selection_Data *sel;
+
+ sel = data;
+ free(sel->data);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_files(const char *target, void *_data, int size, int format __UNUSED__)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ char *data = _data;
+ int i, is;
+ char *tmp;
+
+ if (strcmp(target, "text/uri-list") &&
+ strcmp(target, "_NETSCAPE_URL"))
+ return NULL;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files));
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free;
+
+ if (data[size - 1])
+ {
+ /* Isn't nul terminated */
+ size++;
+ data = realloc(data, size);
+ data[size - 1] = 0;
+ }
+
+ tmp = malloc(size);
+ i = 0;
+ is = 0;
+ while ((is < size) && (data[is]))
+ {
+ if ((i == 0) && (data[is] == '#'))
+ {
+ for (; ((data[is]) && (data[is] != '\n')); is++);
+ }
+ else
+ {
+ if ((data[is] != '\r') &&
+ (data[is] != '\n'))
+ {
+ tmp[i++] = data[is++];
+ }
+ else
+ {
+ while ((data[is] == '\r') || (data[is] == '\n')) is++;
+ tmp[i] = 0;
+ sel->num_files++;
+ sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ tmp[0] = 0;
+ i = 0;
+ }
+ }
+ }
+ if (i > 0)
+ {
+ tmp[i] = 0;
+ sel->num_files++;
+ sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ }
+ free(tmp);
+ free(data);
+
+ ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES;
+ ECORE_X_SELECTION_DATA(sel)->length = sel->num_files;
+
+ return ECORE_X_SELECTION_DATA(sel);
+}
+
+static int
+_ecore_x_selection_data_files_free(void *data)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ int i;
+
+ sel = data;
+ if (sel->files)
+ {
+ for (i = 0; i < sel->num_files; i++)
+ free(sel->files[i]);
+ free(sel->files);
+ }
+ free(sel);
+ return 0;
+}
+
+static void *
+_ecore_x_selection_parser_text(const char *target __UNUSED__,
+ void *_data,
+ int size,
+ int format __UNUSED__)
+{
+ Ecore_X_Selection_Data_Text *sel;
+ char *data = _data;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
+
+ if (data[size - 1])
+ {
+ /* Isn't nul terminated */
+ size++;
+ data = realloc(data, size);
+ data[size - 1] = 0;
+ }
+
+ sel->text = (char *)data;
+ ECORE_X_SELECTION_DATA(sel)->length = size;
+ ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT;
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_text_free(void *data)
+{
+ Ecore_X_Selection_Data_Text *sel;
+
+ sel = data;
+ free(sel->text);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_targets(const char *target __UNUSED__,
+ void *data,
+ int size,
+ int format __UNUSED__)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ uint32_t *targets;
+ xcb_get_atom_name_cookie_t *cookies;
+ int i;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets));
+ targets = (uint32_t *)data;
+
+ sel->num_targets = size - 2;
+ sel->targets = malloc((size - 2) * sizeof(char *));
+ cookies = (xcb_get_atom_name_cookie_t *)malloc ((size - 2) * sizeof (xcb_get_atom_name_cookie_t));
+ for (i = 0; i < size - 2; i++)
+ cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i + 2]);
+
+ /* FIXME: do we let the declaration of reply inside the loop ? */
+ for (i = 0; i < size - 2; i++)
+ {
+ xcb_get_atom_name_reply_t *reply;
+ char *name;
+ int length;
+
+ reply =xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
+ length = xcb_get_atom_name_name_length(reply);
+ name = (char *)malloc (length + 1);
+ memcpy(name, xcb_get_atom_name_name(reply), length);
+ name[length] = '\0';
+ sel->targets[i - 2] = name;
+ }
+ free(cookies);
+ free(data);
+
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_targets_free;
+ ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS;
+ ECORE_X_SELECTION_DATA(sel)->length = size;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_targets_free(void *data)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ int i;
+
+ sel = data;
+
+ if (sel->targets)
+ {
+ for (i = 0; i < sel->num_targets; i++)
+ free(sel->targets[i]);
+ free(sel->targets);
+ }
+ free(sel);
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Shape_Group X Shape extension
+ *
+ * Functions that use the shape extension of the X server to change shape of given windows.
+ */
+
+
+#ifdef ECORE_XCB_SHAPE
+static int _shape_available = 0;
+static xcb_shape_query_version_cookie_t _ecore_xcb_shape_init_cookie;
+#endif /* ECORE_XCB_SHAPE */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_shape_init and
+ _ecore_xcb_shape_init_finalize. The first one gets the cookies and
+ the second one gets the replies. */
+
+void
+_ecore_x_shape_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_SHAPE
+ if (reply && (reply->present))
+ _ecore_xcb_shape_init_cookie = xcb_shape_query_version_unchecked(_ecore_xcb_conn);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+void
+_ecore_x_shape_init_finalize(void)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_query_version_reply_t *reply;
+
+ reply = xcb_shape_query_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_shape_init_cookie,
+ NULL);
+ if (reply)
+ {
+ _shape_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_SHAPE */
+}
+
+
+/**
+ * Sets the shape of the given window to the given pixmap.
+ * @param dest_win The given window.
+ * @param source_mask A 2-bit depth pixmap that provides the new shape of the window.
+ *
+ * Sets the shape of the window @p dest_win to the pixmap @p source_mask.
+ * @ingroup Ecore_X_Shape_Group
+ */
+EAPI void
+ecore_x_window_shape_mask_set(Ecore_X_Window dest_win,
+ Ecore_X_Pixmap source_mask)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, source_mask);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_window_set(Ecore_X_Window dest_win,
+ Ecore_X_Window shape_win)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, shape_win);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_window_set_xy(Ecore_X_Window dest_win,
+ Ecore_X_Window shape_win,
+ int x,
+ int y)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, x, y, shape_win);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+
+/**
+ * Sets the shape of the given window to a rectangle.
+ * @param dest_win The given window.
+ * @param x The X coordinate of the top left corner of the rectangle.
+ * @param y The Y coordinate of the top left corner of the rectangle.
+ * @param width The width of the rectangle.
+ * @param height The height of the rectangle.
+ *
+ * Sets the shape of the window @p dest_win to a rectangle defined by
+ * @p x, @p y, @p width and @p height.
+ * @ingroup Ecore_X_Shape_Group
+ */
+EAPI void
+ecore_x_window_shape_rectangle_set(Ecore_X_Window dest_win,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = width;
+ rect.height = height;
+ xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 1, &rect);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_rectangles_set(Ecore_X_Window dest_win,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ECORE_XCB_SHAPE
+ if (num > 0)
+ xcb_shape_rectangles(_ecore_xcb_conn,
+ XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING,
+ 0, dest_win, 0, 0, num, (xcb_rectangle_t *)rects);
+ else
+ xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 0, NULL);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_window_add(Ecore_X_Window dest_win,
+ Ecore_X_Window shape_win)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, 0, 0, shape_win);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_window_add_xy(Ecore_X_Window dest_win,
+ Ecore_X_Window shape_win,
+ int x,
+ int y)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, dest_win, x, y, shape_win);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_add(Ecore_X_Window dest_win,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = width;
+ rect.height = height;
+ xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 1, &rect);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_clip(Ecore_X_Window dest_win,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_rectangle_t rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = width;
+ rect.height = height;
+ xcb_shape_rectangles(_ecore_xcb_conn,
+ XCB_SHAPE_SO_INTERSECT, XCB_SHAPE_SK_BOUNDING,
+ 0, dest_win, 0, 0, 1, &rect);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+EAPI void
+ecore_x_window_shape_rectangles_add(Ecore_X_Window dest_win,
+ Ecore_X_Rectangle *rects,
+ int num)
+{
+#ifdef ECORE_XCB_SHAPE
+ if (num > 0)
+ xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, num, (const xcb_rectangle_t *)rects);
+ else
+ xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_BOUNDING, 0, dest_win, 0, 0, 0, NULL);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+
+/**
+ * Sends the ShapeGetRectangles request.
+ * @param window Requested window.
+ * @ingroup Ecore_X_Shape_Group
+ */
+EAPI void
+ecore_x_window_shape_rectangles_get_prefetch(Ecore_X_Window window)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_get_rectangles_cookie_t cookie;
+
+ cookie = xcb_shape_get_rectangles_unchecked(_ecore_xcb_conn, window, XCB_SHAPE_SK_BOUNDING);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+
+/**
+ * Gets the reply of the ShapeGetRectangles request sent by ecore_x_window_shape_rectangles_get_prefetch().
+ * @ingroup Ecore_X_Shape_Group
+ */
+EAPI void
+ecore_x_window_shape_rectangles_get_fetch(void)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_get_rectangles_cookie_t cookie;
+ xcb_shape_get_rectangles_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+
+/**
+ * To document.
+ * @param window Unused.
+ * @param num_ret To document.
+ * @return To document.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_window_shape_rectangles_get_prefetch(), which sends the ShapeGetRectangles request,
+ * then ecore_x_window_shape_rectangles_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Shape_Group
+ */
+EAPI Ecore_X_Rectangle *
+ecore_x_window_shape_rectangles_get(Ecore_X_Window window __UNUSED__,
+ int *num_ret)
+{
+ Ecore_X_Rectangle *rects = NULL;
+ uint32_t num = 0;
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_get_rectangles_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ {
+ if (num_ret) *num_ret = 0;
+ return NULL;
+ }
+
+ num = reply->rectangles_len;
+ rects = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (rects)
+ memcpy (rects,
+ xcb_shape_get_rectangles_rectangles(reply),
+ num * sizeof (Ecore_X_Rectangle));
+ else
+ num = 0;
+#endif /* ECORE_XCB_SHAPE */
+
+ if (num_ret) *num_ret = num;
+
+ return rects;
+}
+
+EAPI void
+ecore_x_window_shape_events_select(Ecore_X_Window dest_win,
+ int on)
+{
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_select_input(_ecore_xcb_conn, dest_win, on ? 1 : 0);
+#endif /* ECORE_XCB_SHAPE */
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Sync_Group X Sync Extension Functions
+ *
+ * Functions related to the X Sync extension.
+ */
+
+
+#ifdef ECORE_XCB_SYNC
+static int _sync_available = 0;
+static xcb_sync_initialize_cookie_t _ecore_xcb_sync_init_cookie;
+#endif /* ECORE_XCB_SYNC */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_sync_init and
+ _ecore_xcb_sync_init_finalize. The first one gets the cookies and
+ the second one gets the replies and set the atoms. */
+
+void
+_ecore_x_sync_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_SYNC
+ if (reply && (reply->present))
+ _ecore_xcb_sync_init_cookie = xcb_sync_initialize_unchecked(_ecore_xcb_conn,
+ XCB_SYNC_MAJOR_VERSION,
+ XCB_SYNC_MINOR_VERSION);
+#endif /* ECORE_XCB_SYNC */
+}
+
+void
+_ecore_x_sync_init_finalize(void)
+{
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_initialize_reply_t *reply;
+
+ reply = xcb_sync_initialize_reply(_ecore_xcb_conn,
+ _ecore_xcb_sync_init_cookie, NULL);
+
+ if (reply)
+ {
+ if (reply->major_version >= 3)
+ _sync_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_SYNC */
+}
+
+
+/**
+ * Return whether the X server supports the Sync Extension.
+ * @return 1 if the X Sync Extension is available, 0 otherwise.
+ *
+ * Return 1 if the X server supports the Sync Extension version 3.0,
+ * 0 otherwise.
+ * @ingroup Ecore_X_Sync_Group
+ */
+EAPI int
+ecore_x_sync_query(void)
+{
+#ifdef ECORE_XCB_SYNC
+ return _sync_available;
+#else
+ return 0;
+#endif /* ECORE_XCB_SYNC */
+}
+
+
+/**
+ * Create a new alarm.
+ * @param counter A counter.
+ * @return A newly created alarm.
+ *
+ * Create a new alarm.
+ * @ingroup Ecore_X_Sync_Group
+ */
+EAPI Ecore_X_Sync_Alarm
+ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter)
+{
+#ifdef ECORE_XCB_SYNC
+ uint32_t value_list[6];
+ xcb_sync_int64_t init;
+ Ecore_X_Sync_Alarm alarm;
+ uint32_t value_mask;
+
+ init.lo = 0;
+ init.hi = 0;
+ xcb_sync_set_counter(_ecore_xcb_conn, counter, init);
+
+ value_mask =
+ XCB_SYNC_CA_COUNTER | XCB_SYNC_CA_VALUE_TYPE |
+ XCB_SYNC_CA_VALUE | XCB_SYNC_CA_TEST_TYPE |
+ XCB_SYNC_CA_DELTA | XCB_SYNC_CA_EVENTS;
+ value_list[0] = counter;
+ value_list[1] = XCB_SYNC_VALUETYPE_ABSOLUTE;
+ value_list[2] = 1;
+ value_list[3] = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON;
+ value_list[4] = 1;
+ value_list[5] = 1;
+ alarm = xcb_generate_id(_ecore_xcb_conn);
+ xcb_sync_create_alarm(_ecore_xcb_conn,
+ alarm,
+ value_mask,
+ (const uint32_t *)value_list);
+
+ ecore_x_sync();
+ return alarm;
+#else
+ return 0;
+#endif /* ECORE_XCB_SYNC */
+}
+
+
+/**
+ * Delete an alarm.
+ * @param alarm The alarm to delete.
+ * @return 1 on success, 0 otherwise.
+ *
+ * Delete the @p alarm. Returns 1 on success, 0 otherwise.
+ * @ingroup Ecore_X_Sync_Group
+ */
+EAPI int
+ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm)
+{
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_destroy_alarm(_ecore_xcb_conn, alarm);
+ return 1;
+#else
+ return 0;
+#endif /* ECORE_XCB_SYNC */
+}
+
+/* FIXME: round trip */
+
+EAPI int
+ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val)
+{
+#ifdef ECORE_XCB_SYNC
+ xcb_sync_query_counter_cookie_t cookie;
+ xcb_sync_query_counter_reply_t *reply;
+
+ cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter);
+ reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL);
+ if (reply)
+ {
+ *val = (unsigned int)reply->counter_value.lo;
+ free(reply);
+ return 1;
+ }
+#endif /* ECORE_XCB_SYNC */
+
+ return 0;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include <string.h>
+
+#include <Ecore.h>
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+static int ignore_num = 0;
+static Ecore_X_Window *ignore_list = NULL;
+
+static Ecore_X_Window _ecore_x_window_at_xy_get(Ecore_X_Window base,
+ int16_t base_x,
+ int16_t base_y,
+ int16_t x,
+ int16_t y,
+ Ecore_X_Window *skip,
+ int skip_num);
+
+#ifdef ECORE_XCB_RENDER
+static Ecore_X_Window _ecore_x_window_argb_internal_new(Ecore_X_Window parent,
+ int16_t x,
+ int16_t y,
+ uint16_t w,
+ uint16_t h,
+ uint8_t override_redirect,
+ uint8_t save_under);
+#endif /* ECORE_XCB_RENDER */
+
+
+/**
+ * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
+ *
+ * Functions that can be used to create an X window.
+ */
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ uint32_t value_list[9];
+ Ecore_X_Window window;
+ xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT };
+ uint32_t value_mask;
+
+ if (parent == 0) parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ value_mask =
+ XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
+ XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT |
+ XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
+
+ value_list[0] = XCB_NONE;
+ value_list[1] = 0;
+ value_list[2] = XCB_GRAVITY_NORTH_WEST;
+ value_list[3] = XCB_GRAVITY_NORTH_WEST;
+ value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
+ value_list[5] = 0;
+ value_list[6] = 0;
+ value_list[7] =
+ XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
+ XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
+ XCB_EVENT_MASK_COLOR_MAP_CHANGE;
+ value_list[8] = XCB_EVENT_MASK_NO_EVENT;
+
+ window = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_window(_ecore_xcb_conn,
+ XCB_WINDOW_CLASS_COPY_FROM_PARENT,
+ window, parent, x, y, width, height, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ vis,
+ value_mask,
+ value_list);
+
+ if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root) ecore_x_window_defaults_set(window);
+ return window;
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_override_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ uint32_t value_list[9];
+ Ecore_X_Window window;
+ xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT };
+ uint32_t value_mask;
+
+ if (parent == 0) parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ value_mask =
+ XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
+ XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT |
+ XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
+
+ value_list[0] = XCB_NONE;
+ value_list[1] = 0;
+ value_list[2] = XCB_GRAVITY_NORTH_WEST;
+ value_list[3] = XCB_GRAVITY_NORTH_WEST;
+ value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
+ value_list[5] = 1;
+ value_list[6] = 0;
+ value_list[7] =
+ XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
+ XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
+ XCB_EVENT_MASK_COLOR_MAP_CHANGE;
+ value_list[8] = XCB_EVENT_MASK_NO_EVENT;
+
+ window = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_window(_ecore_xcb_conn,
+ XCB_WINDOW_CLASS_COPY_FROM_PARENT,
+ window, parent, x, y, width, height, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ vis,
+ value_mask,
+ value_list);
+ return window;
+}
+
+/**
+ * Creates a new input window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_input_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ uint32_t value_list[3];
+ Ecore_X_Window window;
+ xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT };
+ uint32_t value_mask;
+
+ if (parent == 0) parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ value_mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
+
+ value_list[0] = 1;
+ value_list[1] =
+ XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
+ XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
+ XCB_EVENT_MASK_COLOR_MAP_CHANGE;
+ value_list[2] = XCB_EVENT_MASK_NO_EVENT;
+
+ window = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_window(_ecore_xcb_conn,
+ XCB_WINDOW_CLASS_COPY_FROM_PARENT,
+ window, parent, x, y, width, height, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ vis,
+ value_mask,
+ value_list);
+
+ if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
+ {
+ }
+
+ return window;
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param width Width.
+ * @param height Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_manager_argb_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ Ecore_X_Window window = 0;
+
+#ifdef ECORE_XCB_RENDER
+ window = _ecore_x_window_argb_internal_new(parent,
+ x, y, width, height,
+ 1, 0);
+#endif /* ECORE_XCB_RENDER */
+
+ return window;
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param width Width.
+ * @param height Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_argb_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ Ecore_X_Window window = 0;
+
+#ifdef ECORE_XCB_RENDER
+ window = _ecore_x_window_argb_internal_new(parent,
+ x, y, width, height,
+ 0, 0);
+#endif /* ECORE_XCB_RENDER */
+
+ return window;
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param width Width.
+ * @param height Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_override_argb_new(Ecore_X_Window parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ Ecore_X_Window window = 0;
+
+#ifdef ECORE_XCB_RENDER
+ window = _ecore_x_window_argb_internal_new(parent,
+ x, y, width, height,
+ 1, 0);
+#endif /* ECORE_XCB_RENDER */
+
+ return window;
+}
+
+/**
+ * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
+ *
+ * Functions to destroy X windows.
+ */
+
+/**
+ * Deletes the given window.
+ * @param window The given window.
+ * @ingroup Ecore_X_Window_Destroy_Group
+ */
+EAPI void
+ecore_x_window_free(Ecore_X_Window window)
+{
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ if (window)
+ xcb_destroy_window(_ecore_xcb_conn, window);
+}
+
+/**
+ * Sends a delete request to the given window.
+ * @param window The given window.
+ * @ingroup Ecore_X_Window_Destroy_Group
+ */
+EAPI void
+ecore_x_window_delete_request_send(Ecore_X_Window window)
+{
+ xcb_client_message_event_t ev;
+
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ if (window == 0)
+ return;
+
+ ev.response_type = XCB_CLIENT_MESSAGE;
+ ev.format = 32;
+ ev.sequence = 0;
+ ev.window = window;
+ ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
+ ev.data.data32[0] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ ev.data.data32[1] = XCB_CURRENT_TIME;
+
+ xcb_send_event(_ecore_xcb_conn, 0, window,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Configure_Group X Window Configure Functions
+ *
+ * Functions to configure X windows.
+ */
+
+
+/**
+ * Configures the given window with the given mask.
+ * @param window The given window.
+ * @param mask The given mask.
+ * @param x The X coordinate of the window.
+ * @param y The Y coordinate of the window.
+ * @param width The width of the window.
+ * @param height The height of the window.
+ * @param border_width The border width of the window.
+ * @param sibling The sibling window of the window.
+ * @param stack_mode The stack mode of the window.
+ * @ingroup Ecore_X_Window_Configure_Group
+ */
+EAPI void
+ecore_x_window_configure(Ecore_X_Window window,
+ Ecore_X_Window_Configure_Mask mask,
+ int x,
+ int y,
+ int width,
+ int height,
+ int border_width,
+ Ecore_X_Window sibling,
+ int stack_mode)
+{
+ uint32_t *value_list;
+ uint32_t value_mask;
+ int length = 0;
+
+ if (!window)
+ return;
+
+ value_mask = mask;
+ for ( ; value_mask; value_mask >>= 1)
+ if (value_mask & 1)
+ length++;
+ value_list = (uint32_t *)malloc(sizeof(uint32_t) * length);
+ if (!value_list)
+ return;
+
+ value_mask = mask;
+ for ( ; value_mask; value_mask >>= 1, value_list++)
+ if (value_mask & 1)
+ {
+ switch (value_mask) {
+ case XCB_CONFIG_WINDOW_X:
+ *value_list = x;
+ break;
+ case XCB_CONFIG_WINDOW_Y:
+ *value_list = y;
+ break;
+ case XCB_CONFIG_WINDOW_WIDTH:
+ *value_list = width;
+ break;
+ case XCB_CONFIG_WINDOW_HEIGHT:
+ *value_list = height;
+ break;
+ case XCB_CONFIG_WINDOW_BORDER_WIDTH:
+ *value_list = border_width;
+ break;
+ case XCB_CONFIG_WINDOW_SIBLING:
+ *value_list = sibling;
+ break;
+ case XCB_CONFIG_WINDOW_STACK_MODE:
+ *value_list = stack_mode;
+ break;
+ }
+ }
+
+ xcb_configure_window(_ecore_xcb_conn, window, mask, value_list);
+ free(value_list);
+}
+
+/**
+ * Moves a window to the position @p x, @p y.
+ *
+ * The position is relative to the upper left hand corner of the
+ * parent window.
+ *
+ * @param window The window to move.
+ * @param x X position.
+ * @param y Y position.
+ * @ingroup Ecore_X_Window_Configure_Group
+ */
+EAPI void
+ecore_x_window_move(Ecore_X_Window window,
+ int x,
+ int y)
+{
+ uint32_t value_list[2];
+ uint32_t value_mask;
+
+ if (!window)
+ return;
+
+ value_mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
+
+ value_list[0] = x;
+ value_list[1] = y;
+
+ xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list);
+}
+
+/**
+ * Resizes a window.
+ * @param window The window to resize.
+ * @param width New width of the window.
+ * @param height New height of the window.
+ * @ingroup Ecore_X_Window_Configure_Group
+ */
+EAPI void
+ecore_x_window_resize(Ecore_X_Window window,
+ int width,
+ int height)
+{
+ uint32_t value_list[2];
+ uint32_t value_mask;
+
+ if (!window)
+ return;
+
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+
+ value_mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
+
+ value_list[0] = width;
+ value_list[1] = height;
+
+ xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list);
+}
+
+/**
+ * Moves and resizes a window.
+ * @param window The window to move and resize.
+ * @param x New X position of the window.
+ * @param y New Y position of the window.
+ * @param width New width of the window.
+ * @param height New height of the window.
+ * @ingroup Ecore_X_Window_Configure_Group
+ */
+EAPI void
+ecore_x_window_move_resize(Ecore_X_Window window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ uint32_t value_list[4];
+ uint32_t value_mask;
+
+ if (!window)
+ return;
+
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+
+ value_mask =
+ XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
+ XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
+
+ value_list[0] = x;
+ value_list[1] = y;
+ value_list[2] = width;
+ value_list[3] = height;
+
+ xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list);
+}
+
+/**
+ * Sets the width of the border of the given window.
+ * @param window The given window.
+ * @param border_width The new border width.
+ * @ingroup Ecore_X_Window_Configure_Group
+ */
+EAPI void
+ecore_x_window_border_width_set(Ecore_X_Window window,
+ int border_width)
+{
+ uint32_t value_list;
+
+ /* doesn't make sense to call this on a root window */
+ if (!window)
+ return;
+
+ value_list = border_width;
+
+ xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_BORDER_WIDTH, &value_list);
+}
+
+/**
+ * Raises the given window.
+ * @param window The window to raise.
+ * @ingroup Ecore_X_Window_Configure_Group
+ */
+EAPI void
+ecore_x_window_raise(Ecore_X_Window window)
+{
+ uint32_t value_list;
+
+ if (!window)
+ return;
+
+ value_list = XCB_STACK_MODE_ABOVE;
+
+ xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_STACK_MODE, &value_list);
+}
+
+/**
+ * Lowers the given window.
+ * @param window The window to lower.
+ * @ingroup Ecore_X_Window_Configure_Group
+ */
+EAPI void
+ecore_x_window_lower(Ecore_X_Window window)
+{
+ uint32_t value_list;
+
+ if (!window)
+ return;
+
+ value_list = XCB_STACK_MODE_BELOW;
+
+ xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_STACK_MODE, &value_list);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Change_Properties_Group X Window Change Property Functions
+ *
+ * Functions that change window properties.
+ */
+
+/**
+ * Sets the default properties for the given window.
+ *
+ * The default properties set for the window are @c WM_CLIENT_MACHINE and
+ * @c _NET_WM_PID.
+ *
+ * @param window The given window.
+ * @ingroup Ecore_X_Window_Change_Property_Group
+ */
+EAPI void
+ecore_x_window_defaults_set(Ecore_X_Window window)
+{
+ char buf[MAXHOSTNAMELEN];
+ pid_t pid;
+ int argc;
+ char **argv;
+
+ /*
+ * Set WM_CLIENT_MACHINE.
+ */
+ gethostname(buf, MAXHOSTNAMELEN);
+ buf[MAXHOSTNAMELEN - 1] = '\0';
+ /* The ecore function uses UTF8 which Xlib may not like (especially
+ * with older clients) */
+ /* ecore_xcb_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE,
+ (char *)buf); */
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ ECORE_X_ATOM_WM_CLIENT_MACHINE,
+ ECORE_X_ATOM_STRING,
+ 8, strlen(buf), buf);
+
+ /*
+ * Set _NET_WM_PID
+ */
+ pid = getpid();
+ ecore_x_netwm_pid_set(window, pid);
+
+ ecore_x_netwm_window_type_set(window, ECORE_X_WINDOW_TYPE_NORMAL);
+
+ ecore_app_args_get(&argc, &argv);
+ ecore_x_icccm_command_set(window, argc, argv);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
+ *
+ * Functions to change the visibility of X windows.
+ */
+
+/**
+ * Shows a window.
+ *
+ * Synonymous to "mapping" a window in X Window System terminology.
+ *
+ * @param window The window to show.
+ * @ingroup Ecore_X_Window_Visibility_Group
+ */
+EAPI void
+ecore_x_window_show(Ecore_X_Window window)
+{
+ xcb_map_window(_ecore_xcb_conn, window);
+}
+
+/**
+ * Hides a window.
+ *
+ * Synonymous to "unmapping" a window in X Window System terminology.
+ *
+ * @param window The window to hide.
+ * @ingroup Ecore_X_Window_Visibility_Group
+ */
+EAPI void
+ecore_x_window_hide(Ecore_X_Window window)
+{
+ xcb_unmap_notify_event_t ev;
+ Ecore_X_Window root;
+
+ /* ICCCM: SEND unmap event... */
+ root = window;
+ /* FIXME: is it correct ? */
+ if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1)
+ root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ else
+ {
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *rep;
+ Ecore_X_Drawable draw;
+
+ /* FIXME: can we avoid round trips, here ? */
+ draw = window;
+ cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, draw);
+ rep = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!rep)
+ return;
+ root = rep->root;
+ free(rep);
+ }
+ ev.response_type = XCB_UNMAP_NOTIFY;
+ ev.pad0 = 0;
+ ev.sequence = 0;
+ ev.event = root;
+ ev.window = window;
+ ev.from_configure = 0;
+
+ xcb_send_event(_ecore_xcb_conn, 0, root,
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
+ (const char *)&ev);
+ xcb_unmap_window(_ecore_xcb_conn, window);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Input_Focus_Group X Window Input Focus Functions
+ *
+ * Functions that manage the focus of an X Window.
+ */
+
+/**
+ * Sets the focus to the window @p window.
+ * @param window The window to focus.
+ * @ingroup Ecore_X_Window_Input_Focus_Group
+ */
+EAPI void
+ecore_x_window_focus(Ecore_X_Window window)
+{
+ Ecore_X_Time time = XCB_CURRENT_TIME;
+
+ if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ /* xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_NONE, win, time); */
+ xcb_set_input_focus(_ecore_xcb_conn,
+ XCB_INPUT_FOCUS_POINTER_ROOT, window, time);
+}
+
+/**
+ * Sets the focus to the given window at a specific time.
+ * @param window The window to focus.
+ * @param time When to set the focus to the window.
+ * @ingroup Ecore_X_Window_Input_Focus_Group
+ */
+EAPI void
+ecore_x_window_focus_at_time(Ecore_X_Window window,
+ Ecore_X_Time time)
+{
+ if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ /* xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_NONE, win, time); */
+ xcb_set_input_focus(_ecore_xcb_conn,
+ XCB_INPUT_FOCUS_POINTER_ROOT, window, time);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Reparent_Group X Window Reparent Functions
+ *
+ * Functions that retrieve or changes the parent window of a window.
+ */
+
+/**
+ * Moves a window to within another window at a given position.
+ * @param window The window to reparent.
+ * @param new_parent The new parent window.
+ * @param x X position within new parent window.
+ * @param y Y position within new parent window.
+ * @ingroup Ecore_X_Window_Reparent_Group
+ */
+EAPI void
+ecore_x_window_reparent(Ecore_X_Window window,
+ Ecore_X_Window new_parent,
+ int x,
+ int y)
+{
+ if (new_parent == 0) new_parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ xcb_reparent_window(_ecore_xcb_conn, window, new_parent, x, y);
+}
+
+
+/**
+ * @defgroup Ecore_X_Window_Change_Attributes_Group X Window Change Attributes Functions
+ *
+ * Functions that change the attributes of a window.
+ */
+
+/**
+ * Sets the background pixmap of the given window.
+ * @param window The given window.
+ * @param pixmap The pixmap to set to.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_pixmap_set(Ecore_X_Window window,
+ Ecore_X_Pixmap pixmap)
+{
+ uint32_t value_list;
+
+ value_list = pixmap;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_BACK_PIXMAP, &value_list);
+}
+
+/**
+ * Sets the background color of the given window.
+ * @param window The given window.
+ * @param red The red component of the color to set to.
+ * @param green The green component of the color to set to.
+ * @param blue The blue component of the color to set to.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_background_color_set(Ecore_X_Window window,
+ unsigned short red,
+ unsigned short green,
+ unsigned short blue)
+{
+ xcb_alloc_color_cookie_t cookie;
+ xcb_alloc_color_reply_t *rep;
+ uint32_t value_list;
+
+ /* FIXME: should I provide a reply, and not the color components, here ? */
+ /* (because of roundtrips) */
+ cookie = xcb_alloc_color_unchecked(_ecore_xcb_conn,
+ ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap,
+ red, green, blue);
+ rep = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL);
+ if (!rep)
+ return;
+
+ value_list = rep->pixel;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_BACK_PIXEL, &value_list);
+ free(rep);
+}
+
+/**
+ * Sets the bit gravity of the given window.
+ * @param window The given window.
+ * @param gravity The gravity.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_pixel_gravity_set(Ecore_X_Window window,
+ Ecore_X_Gravity gravity)
+{
+ uint32_t value_list;
+
+ value_list = gravity;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_BIT_GRAVITY, &value_list);
+}
+
+/**
+ * Sets the gravity of the given window.
+ * @param window The given window.
+ * @param gravity The gravity.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_gravity_set(Ecore_X_Window window,
+ Ecore_X_Gravity gravity)
+{
+ uint32_t value_list;
+
+ value_list = gravity;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_WIN_GRAVITY, &value_list);
+}
+
+/**
+ * Sets the override attribute of the given window.
+ * @param window The given window.
+ * @param override_redirect The override_redirect boolean.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_override_set(Ecore_X_Window window,
+ int override_redirect)
+{
+ uint32_t value_list;
+
+ value_list = override_redirect;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_OVERRIDE_REDIRECT, &value_list);
+}
+
+/**
+ * Shows the cursor of the given window.
+ * @param window The given window.
+ * @param show If set to @c 0, hide the cursor. Show it otherwise.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_cursor_show(Ecore_X_Window window,
+ int show)
+{
+ if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ if (!show)
+ {
+ Ecore_X_Cursor cursor;
+ Ecore_X_Drawable draw;
+ Ecore_X_Pixmap pixmap;
+ Ecore_X_Pixmap mask;
+ Ecore_X_GC gc;
+ xcb_point_t point;
+ uint32_t value_list;
+
+ draw = window;
+ pixmap = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn,
+ 1, pixmap, draw,
+ 1, 1);
+ mask = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_pixmap(_ecore_xcb_conn,
+ 1, mask, draw,
+ 1, 1);
+
+ gc = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_gc (_ecore_xcb_conn, gc, draw, 0, NULL);
+ value_list = 0;
+ xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &value_list);
+
+ draw = mask;
+ point.x = 0;
+ point.y = 0;
+ xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN, draw,
+ gc, 1, &point);
+
+ xcb_free_gc(_ecore_xcb_conn, gc);
+
+ cursor = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_cursor(_ecore_xcb_conn, cursor,
+ pixmap, mask,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0);
+ value_list = cursor;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_CURSOR, &value_list);
+
+ xcb_free_cursor(_ecore_xcb_conn, cursor);
+ xcb_free_pixmap(_ecore_xcb_conn, mask);
+ xcb_free_pixmap(_ecore_xcb_conn, pixmap);
+ }
+ else
+ {
+ uint32_t value_list;
+
+ value_list = 0;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_CURSOR, &value_list);
+ }
+}
+
+/**
+ * Sets the cursor of the given window.
+ * @param window The given window.
+ * @param cursor The given cursor.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_cursor_set(Ecore_X_Window window,
+ Ecore_X_Cursor cursor)
+{
+ uint32_t value_list;
+
+ value_list = cursor;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_CURSOR, &value_list);
+}
+
+/**
+ * Todo
+ * @param window The given window.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_container_manage(Ecore_X_Window window)
+{
+ uint32_t value_list;
+
+ value_list =
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_EVENT_MASK, &value_list);
+
+}
+
+/**
+ * Todo
+ * @param window The given window.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_client_manage(Ecore_X_Window window)
+{
+ uint32_t value_list;
+
+ value_list =
+ XCB_EVENT_MASK_VISIBILITY_CHANGE |
+/* XCB_EVENT_MASK_RESIZE_REDIRECT | */
+ XCB_EVENT_MASK_STRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_FOCUS_CHANGE |
+ XCB_EVENT_MASK_PROPERTY_CHANGE |
+ XCB_EVENT_MASK_COLOR_MAP_CHANGE;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_EVENT_MASK, &value_list);
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_select_input(_ecore_xcb_conn, window, 1);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+/**
+ * Todo
+ * @param window The given window.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_sniff(Ecore_X_Window window)
+{
+ uint32_t value_list;
+
+ value_list =
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_PROPERTY_CHANGE;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_EVENT_MASK, &value_list);
+}
+
+/**
+ * Todo
+ * @param window The given window.
+ * @ingroup Ecore_X_Window_Change_Attributes_Group
+ */
+EAPI void
+ecore_x_window_client_sniff(Ecore_X_Window window)
+{
+ uint32_t value_list;
+
+ value_list =
+ XCB_EVENT_MASK_VISIBILITY_CHANGE |
+ XCB_EVENT_MASK_STRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_FOCUS_CHANGE |
+ XCB_EVENT_MASK_PROPERTY_CHANGE |
+ XCB_EVENT_MASK_COLOR_MAP_CHANGE;
+ xcb_change_window_attributes(_ecore_xcb_conn, window,
+ XCB_CW_EVENT_MASK, &value_list);
+#ifdef ECORE_XCB_SHAPE
+ xcb_shape_select_input(_ecore_xcb_conn, window, 1);
+#endif /* ECORE_XCB_SHAPE */
+}
+
+/**
+ * Clears an area of the given window.
+ * @param window The given window.
+ * @param x The X coordinate of the area.
+ * @param y The Y coordinate of the area.
+ * @param width The width of the area.
+ * @param height The height of the area.
+ * @ingroup Ecore_X_Window_Clear_Area_Group
+ */
+EAPI void
+ecore_x_window_area_clear(Ecore_X_Window window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ xcb_clear_area(_ecore_xcb_conn, 0, window, x, y, width, height);
+}
+
+/**
+ * Exposes an area of the given window.
+ * @param window The given window.
+ * @param x The X coordinate of the area.
+ * @param y The Y coordinate of the area.
+ * @param width The width of the area.
+ * @param height The height of the area.
+ * @ingroup Ecore_X_Window_Clear_Area_Group
+ */
+EAPI void
+ecore_x_window_area_expose(Ecore_X_Window window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ xcb_clear_area(_ecore_xcb_conn, 1, window, x, y, width, height);
+}
+
+
+/**
+ * @defgroup Ecore_X_Window_Save_Set_Group X Window Change Save Set Functions
+ *
+ * Functions that either inserts or deletes the specified window from
+ * the client's save-set.
+ */
+
+/**
+ * Inserts the window in the client's save-set.
+ * @param window The window to insert in the client's save-set.
+ * @ingroup Ecore_X_Window_Save_Set_Group
+ */
+EAPI void
+ecore_x_window_save_set_add(Ecore_X_Window window)
+{
+ xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, window);
+}
+
+/**
+ * Deletes the window from the client's save-set.
+ * @param window The window to delete from the client's save-set.
+ * @ingroup Ecore_X_Window_Save_Set_Group
+ */
+EAPI void
+ecore_x_window_save_set_del(Ecore_X_Window window)
+{
+ xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, window);
+}
+
+/******************************
+ *
+ * Request that have a reply
+ *
+ ******************************/
+
+
+/**
+ * Sends the GetInputFocus request.
+ * @ingroup Ecore_X_Window_Input_Focus_Group
+ */
+EAPI void
+ecore_x_get_input_focus_prefetch(void)
+{
+ xcb_get_input_focus_cookie_t cookie;
+
+ cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetInputFocus request sent by ecore_x_get_input_focus_prefetch().
+ * @ingroup Ecore_X_Window_Input_Focus_Group
+ */
+EAPI void
+ecore_x_get_input_focus_fetch(void)
+{
+ xcb_get_input_focus_cookie_t cookie;
+ xcb_get_input_focus_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Gets the window that has focus.
+ * @return The window that has focus.
+ *
+ * Returns the window that has the focus. If an error aoocured, @c 0
+ * is returned, otherwise the function returns the window that has focus.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_input_focus_prefetch(), which sends the GetInputFocus request,
+ * then ecore_x_get_input_focus_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Input_Focus_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_focus_get(void)
+{
+ xcb_get_input_focus_reply_t *reply;
+ Ecore_X_Window window = 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return window;
+
+ return reply->focus;
+}
+
+
+/**
+ * @defgroup Ecore_X_Window_Get_Attributes_Group X Window Get Attributes Functions
+ *
+ * Functions that get the attributes of a window.
+ */
+
+
+/**
+ * Sends the GetWindowAttributes request.
+ * @ingroup Ecore_X_Window_Get_Attributes_Group
+ */
+EAPI void
+ecore_x_get_window_attributes_prefetch(Ecore_X_Window window)
+{
+ xcb_get_window_attributes_cookie_t cookie;
+
+ cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the GetWindowAttributes request sent by ecore_x_get_window_attributes_prefetch().
+ * @ingroup Ecore_X_Window_Get_Attributes_Group
+ */
+EAPI void
+ecore_x_get_window_attributes_fetch(void)
+{
+ xcb_get_window_attributes_cookie_t cookie;
+ xcb_get_window_attributes_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Retrieves the attributes of a window.
+ * @param windows Unused.
+ * @param att_ret Pointer to an Ecore_X_Window_Attributes
+ * structure in which the attributes of a window
+ * are to be stored.
+ *
+ * Retrieves the attributes of a window. If
+ * @p att_ret is @c NULL, the function does nothing. If an error
+ * occurred, @p att_ret is set to 0. Otherwise, the @p att_ret structure
+ * is filled with the attributes os the requested window.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_window_attributes_prefetch(), which sends the GetWindowAttributes request,
+ * then ecore_x_get_window_attributes_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Get_Attributes_Group
+ */
+EAPI int
+ecore_x_window_attributes_get(Ecore_X_Window window __UNUSED__,
+ Ecore_X_Window_Attributes *att_ret)
+{
+ xcb_get_window_attributes_reply_t *reply;
+
+ if (!att_ret) return 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
+
+ if (reply->map_state != XCB_MAP_STATE_UNMAPPED) att_ret->visible = 1;
+ if (reply->map_state == XCB_MAP_STATE_VIEWABLE) att_ret->viewable = 1;
+ if (reply->override_redirect) att_ret->override = 1;
+ if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY) att_ret->input_only = 1;
+ if (reply->save_under) att_ret->save_under = 1;
+
+ att_ret->event_mask.mine = reply->your_event_mask;
+ att_ret->event_mask.all = reply->all_event_masks;
+ att_ret->event_mask.no_propagate = reply->do_not_propagate_mask;
+ att_ret->window_gravity = reply->win_gravity;
+ att_ret->pixel_gravity = reply->bit_gravity;
+ att_ret->colormap = reply->colormap;
+ att_ret->visual = reply->visual;
+
+ return 1;
+}
+
+/**
+ * Finds out whether the given window is currently visible.
+ * @param window Unused.
+ * @return 1 if the window is visible, otherwise 0.
+ *
+ * Finds out whether the given window is currently visible.
+ * If an error occurred, or if the window is not visible, 0 is
+ * returned. Otherwise 1 is returned.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_get_window_attributes_prefetch(), which sends the GetWindowAttributes request,
+ * then ecore_x_get_window_attributes_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Get_Attributes_Group
+ */
+EAPI int
+ecore_x_window_visible_get(Ecore_X_Window window __UNUSED__)
+{
+ xcb_get_window_attributes_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ return (reply->map_state == XCB_MAP_STATE_VIEWABLE) ? 1 : 0;
+}
+
+
+/**
+ * Sends the QueryPointer request.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI void
+ecore_x_pointer_xy_get_prefetch(Ecore_X_Window window)
+{
+ xcb_query_pointer_cookie_t cookie;
+
+ cookie = xcb_query_pointer_unchecked(_ecore_xcb_conn, window);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the QueryPointer request sent by ecore_x_query_pointer_prefetch().
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI void
+ecore_x_pointer_xy_get_fetch(void)
+{
+ xcb_query_pointer_cookie_t cookie;
+ xcb_query_pointer_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_query_pointer_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Retrieves the coordinates of the pointer.
+ * @param window Unused.
+ * @param x The X coordinate of the pointer.
+ * @param y The Y coordinate of the pointer.
+ *
+ * Retrieves the coordinates of the pointer.
+ * If the window used in
+ * ecore_x_query_pointer_prefetch() is not on the same screen than
+ * the root window or if an error occured, @p x and @p y are set
+ * to 0. Otherwise, they are respectively set to the X and Y
+ * coordinates of the pointer.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_query_pointer_prefetch(), which sends the QueryPointer request,
+ * then ecore_x_query_pointer_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI void
+ecore_x_pointer_xy_get(Ecore_X_Window window __UNUSED__,
+ int *x,
+ int *y)
+{
+ xcb_query_pointer_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ {
+ if (x) *x = 0;
+ if (y) *y = 0;
+
+ return;
+ }
+
+ if (x) *x = reply->win_x;
+ if (y) *y = reply->win_y;
+}
+
+
+/**
+ * Sends the QueryTree request.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI void
+ecore_x_query_tree_prefetch(Ecore_X_Window window)
+{
+ xcb_query_tree_cookie_t cookie;
+
+ cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, window);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+/**
+ * Gets the reply of the QueryTree request sent by ecore_x_query_tree_prefetch().
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI void
+ecore_x_query_tree_fetch(void)
+{
+ xcb_query_tree_cookie_t cookie;
+ xcb_query_tree_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Retrieves the parent window of the given window.
+ * @param window Unused.
+ * @return The parent window of @p window.
+ *
+ * Retrieves the parent window of the given window. If
+ * an error occured, @c 0 is returned.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_query_tree_prefetch(), which sends the QueryTree request,
+ * then ecore_x_query_tree_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_parent_get(Ecore_X_Window window __UNUSED__)
+{
+ xcb_query_tree_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ return reply->parent;
+}
+
+
+/**
+ * Retrieves the children windows of the given window.
+ * @param window Unused.
+ * @param num children windows count.
+ * @return The children windows.
+ *
+ * Retrieves the children windows of the given window. If
+ * an error occured, @c 0 is returned.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_query_tree_prefetch(), which sends the QueryTree request,
+ * then ecore_x_query_tree_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI Ecore_X_Window *
+ecore_x_window_children_get(Ecore_X_Window window __UNUSED__,
+ int *num)
+{
+ xcb_query_tree_reply_t *reply;
+ Ecore_X_Window *windows = NULL;
+
+ if (num) *num = 0;
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return NULL;
+
+ windows = malloc(sizeof(Ecore_X_Window) * reply->children_len);
+ if (!windows)
+ return NULL;
+
+ if (num) *num = reply->children_len;
+ memcpy(windows,
+ xcb_query_tree_children(reply),
+ sizeof(Ecore_X_Window) * reply->children_len);
+
+ return windows;
+}
+
+/* FIXME: I've tried to remove the round trips. 3 cookies are */
+/* created at the beginning of the function. Because of */
+/* the recursivity of the algo, I can't find better trick */
+static Ecore_X_Window
+_ecore_x_window_at_xy_get(Ecore_X_Window base,
+ int16_t base_x,
+ int16_t base_y,
+ int16_t x,
+ int16_t y,
+ Ecore_X_Window *skip,
+ int skip_num)
+{
+ xcb_window_iterator_t iter_children;
+ xcb_get_window_attributes_cookie_t cookie_get_window_attributes;
+ xcb_get_geometry_cookie_t cookie_get_geometry;
+ xcb_query_tree_cookie_t cookie_query_tree;
+ xcb_get_window_attributes_reply_t *reply_get_window_attributes;
+ xcb_get_geometry_reply_t *reply_get_geometry;
+ xcb_query_tree_reply_t *reply_query_tree;
+ Ecore_X_Window window = 0;
+ Ecore_X_Window child = 0;
+ int16_t win_x;
+ int16_t win_y;
+ uint16_t win_width;
+ uint16_t win_height;
+
+ cookie_get_window_attributes = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, base);
+ cookie_get_geometry = xcb_get_geometry_unchecked(_ecore_xcb_conn, base);
+ cookie_query_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, base);
+
+ reply_get_window_attributes = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_get_window_attributes, NULL);
+ if (!reply_get_window_attributes)
+ {
+ reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL);
+ if (reply_get_geometry) free(reply_get_geometry);
+ reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
+ if (reply_query_tree) free(reply_query_tree);
+ return window;
+ }
+
+ if (reply_get_window_attributes->map_state != XCB_MAP_STATE_VIEWABLE)
+ {
+ free(reply_get_window_attributes);
+ reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL);
+ if (reply_get_geometry) free(reply_get_geometry);
+ reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
+ if (reply_query_tree) free(reply_query_tree);
+ return window;
+ }
+
+ free(reply_get_window_attributes);
+
+ reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL);
+ if (!reply_get_geometry)
+ {
+ reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
+ if (reply_query_tree) free(reply_query_tree);
+ return window;
+ }
+
+ win_x = reply_get_geometry->x;
+ win_y = reply_get_geometry->y;
+ win_width = reply_get_geometry->width;
+ win_height = reply_get_geometry->height;
+
+ free(reply_get_geometry);
+
+ win_x += base_x;
+ win_y += base_y;
+
+ if (!((x >= win_x) &&
+ (y >= win_y) &&
+ (x < (int16_t)(win_x + win_width)) &&
+ (y < (int16_t)(win_y + win_height))))
+ {
+ reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
+ if (reply_query_tree) free(reply_query_tree);
+ return window;
+ }
+
+ reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
+ if (!reply_query_tree)
+ {
+ if (skip)
+ {
+ int i;
+
+ for (i = 0; i < skip_num; i++)
+ if (base == skip[i])
+ return window;
+ }
+ return base;
+ }
+
+ iter_children = xcb_query_tree_children_iterator(reply_query_tree);
+ for (; iter_children.rem; xcb_window_next(&iter_children))
+ {
+ if (skip)
+ {
+ int j;
+
+ for (j = 0; j < skip_num; j++)
+ if (*iter_children.data == skip[j])
+ continue;
+ }
+ child = _ecore_x_window_at_xy_get(*iter_children.data, win_x, win_y, x, y, skip, skip_num);
+ if (child)
+ {
+ free(reply_query_tree);
+
+ return child;
+ }
+ }
+
+ if (skip)
+ {
+ int i;
+
+ for (i = 0; i < skip_num; i++)
+ if (base == skip[i])
+ {
+ /* We return 0. child has an xid equal to 0 */
+ free(reply_query_tree);
+ return child;
+ }
+ }
+
+ free(reply_query_tree);
+
+ return base;
+}
+
+/**
+ * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
+ *
+ * Functions that change or retrieve the geometry of X windows.
+ */
+
+/**
+ * Retrieves the top, visible window at the given location.
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_get(int x,
+ int y)
+{
+ Ecore_X_Window window;
+ Ecore_X_Window root;
+
+ /* FIXME: Proper function to determine current root/virtual root
+ * window missing here */
+ root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ecore_x_grab();
+ window = _ecore_x_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ return window ? window : root;
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but skips the windows in the list.
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_with_skip_get(int x,
+ int y,
+ Ecore_X_Window *skip,
+ int skip_num)
+{
+ Ecore_X_Window window;
+ Ecore_X_Window root;
+
+ /* FIXME: Proper function to determine current root/virtual root
+ * window missing here */
+ root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ecore_x_grab();
+ window = _ecore_x_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
+ ecore_x_ungrab();
+
+ return window ? window : root;
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but begins at the @p begin window instead of the root one.
+ * @param begin The window from which we begin.
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
+ int x,
+ int y)
+{
+ Ecore_X_Window window;
+
+ ecore_x_grab();
+ window = _ecore_x_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ return window ? window : begin;
+}
+
+
+
+/* FIXME: Should I provide the replies (or the cookies), instead of
+ creating them in the function ? */
+#ifdef ECORE_XCB_RENDER
+static Ecore_X_Window
+_ecore_x_window_argb_internal_new(Ecore_X_Window parent,
+ int16_t x,
+ int16_t y,
+ uint16_t w,
+ uint16_t h,
+ uint8_t override_redirect,
+ uint8_t save_under)
+{
+ uint32_t value_list[10];
+ xcb_depth_iterator_t iter_depth;
+ xcb_visualtype_iterator_t iter_visualtype;
+ xcb_render_query_pict_formats_cookie_t cookie_pict_format;
+ xcb_render_query_pict_formats_reply_t *rep_pict_format;
+ Ecore_X_Screen *screen = NULL;
+ Ecore_X_Window win = { 0 };
+ xcb_visualid_t vis = { 0 };
+ Ecore_X_Colormap colormap;
+ uint32_t value_mask;
+
+ cookie_pict_format = xcb_render_query_pict_formats_unchecked(_ecore_xcb_conn);
+
+ if (parent == 0)
+ {
+ parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ screen = ((xcb_screen_t *)_ecore_xcb_screen);
+ }
+ else
+ {
+ xcb_screen_iterator_t iter_screen;
+ xcb_get_geometry_reply_t *rep;
+ Ecore_X_Drawable draw;
+ Ecore_X_Window root;
+
+ draw = parent;
+ rep = xcb_get_geometry_reply(_ecore_xcb_conn,
+ xcb_get_geometry_unchecked(_ecore_xcb_conn,
+ draw),
+ NULL);
+ if (!rep)
+ return win;
+
+ root = rep->root;
+
+ free(rep);
+
+ for (; iter_screen.rem; xcb_screen_next(&iter_screen))
+ {
+ if (iter_screen.data->root == root)
+ {
+ screen = iter_screen.data;
+ }
+ }
+ }
+ if (!screen)
+ return win;
+
+ /* we get the X visual types */
+ iter_depth = xcb_screen_allowed_depths_iterator(screen);
+ for (; iter_depth.rem; xcb_depth_next(&iter_depth)) {
+ if (iter_depth.data->depth == 32) {
+ iter_visualtype = xcb_depth_visuals_iterator(iter_depth.data);
+ break;
+ }
+ }
+
+ /* we get the X render visual id */
+ rep_pict_format = xcb_render_query_pict_formats_reply(_ecore_xcb_conn,
+ cookie_pict_format,
+ NULL);
+ if (!rep_pict_format)
+ return win;
+
+ for (; iter_visualtype.rem; xcb_visualtype_next(&iter_visualtype)) {
+ if (iter_visualtype.data->_class == XCB_VISUAL_CLASS_TRUE_COLOR) {
+ xcb_render_pictforminfo_iterator_t iter_forminfo;
+ xcb_render_pictscreen_iterator_t iter_pictscreen;
+ xcb_render_pictformat_t pict_format = { 0 };
+
+ iter_forminfo = xcb_render_query_pict_formats_formats_iterator(rep_pict_format);
+ for (; iter_forminfo.rem; xcb_render_pictforminfo_next(&iter_forminfo)) {
+ if (iter_forminfo.data->type == XCB_RENDER_PICT_TYPE_DIRECT &&
+ iter_forminfo.data->direct.alpha_mask && iter_forminfo.data->depth == 32) {
+ pict_format = iter_forminfo.data->id;
+ break;
+ }
+ }
+ if (pict_format == 0) {
+ free(rep_pict_format);
+ return win;
+ }
+ iter_pictscreen = xcb_render_query_pict_formats_screens_iterator(rep_pict_format);
+ for (; iter_pictscreen.rem; xcb_render_pictscreen_next(&iter_pictscreen)) {
+ xcb_render_pictdepth_iterator_t iter_depth;
+
+ iter_depth = xcb_render_pictscreen_depths_iterator(iter_pictscreen.data);
+ for (; iter_depth.rem; xcb_render_pictdepth_next(&iter_depth)) {
+ xcb_render_pictvisual_iterator_t iter_visual;
+
+ iter_visual = xcb_render_pictdepth_visuals_iterator(iter_depth.data);
+ for (; iter_visual.rem; xcb_render_pictvisual_next(&iter_visual)) {
+ if ((iter_visual.data->visual == iter_visualtype.data->visual_id) &&
+ (pict_format == iter_visual.data->format)) {
+ vis = iter_visual.data->visual;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ free(rep_pict_format);
+
+ if (vis == 0)
+ return win;
+
+ colormap = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, parent, vis);
+
+ value_mask =
+ XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
+ XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT |
+ XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE |
+ XCB_CW_COLORMAP;
+
+ value_list[0] = XCB_NONE;
+ value_list[1] = 0;
+ value_list[2] = XCB_GRAVITY_NORTH_WEST;
+ value_list[3] = XCB_GRAVITY_NORTH_WEST;
+ value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
+ value_list[5] = override_redirect;
+ value_list[6] = save_under;
+ value_list[7] =
+ XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
+ XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
+ XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
+ XCB_EVENT_MASK_COLOR_MAP_CHANGE;
+ value_list[8] = XCB_EVENT_MASK_NO_EVENT;
+ value_list[9] = colormap;
+
+ win = xcb_generate_id(_ecore_xcb_conn);
+ xcb_create_window(_ecore_xcb_conn,
+ 32, /* depth */
+ win, parent,
+ x, y, w, h, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ vis,
+ value_mask,
+ value_list);
+
+ xcb_free_colormap(_ecore_xcb_conn, colormap);
+
+ if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
+ ecore_x_window_defaults_set(win);
+
+ return win;
+}
+#endif /* ECORE_XCB_RENDER */
+
+
+
+/* FIXME: round trip */
+EAPI int
+ecore_x_window_argb_get(Ecore_X_Window win)
+{
+ uint8_t ret = 0;
+#ifdef ECORE_XCB_RENDER
+ xcb_render_pictforminfo_iterator_t iter_forminfo;
+ xcb_render_pictscreen_iterator_t iter_pictscreen;
+ xcb_render_pictformat_t pict_format = { 0 };
+ xcb_render_query_pict_formats_reply_t *rep_pictformat;
+ xcb_get_window_attributes_reply_t *rep;
+ xcb_visualid_t visual;
+
+ rep = xcb_get_window_attributes_reply(_ecore_xcb_conn,
+ xcb_get_window_attributes_unchecked(_ecore_xcb_conn,
+ win),
+ NULL);
+ if (!rep)
+ return ret;
+
+ visual = rep->visual;
+
+ free(rep);
+
+ rep_pictformat = xcb_render_query_pict_formats_reply(_ecore_xcb_conn,
+ xcb_render_query_pict_formats_unchecked(_ecore_xcb_conn),
+ NULL);
+ if (!rep_pictformat)
+ return ret;
+
+ iter_forminfo = xcb_render_query_pict_formats_formats_iterator(rep_pictformat);
+ for (; iter_forminfo.rem; xcb_render_pictforminfo_next(&iter_forminfo))
+ {
+ if ((iter_forminfo.data->type == XCB_RENDER_PICT_TYPE_DIRECT) &&
+ (iter_forminfo.data->direct.alpha_mask))
+ {
+ pict_format = iter_forminfo.data->id;
+ break;
+ }
+ }
+ if (pict_format == 0)
+ {
+ free(rep_pictformat);
+
+ return ret;
+ }
+
+ iter_pictscreen = xcb_render_query_pict_formats_screens_iterator(rep_pictformat);
+ for (; iter_pictscreen.rem; xcb_render_pictscreen_next(&iter_pictscreen))
+ {
+ xcb_render_pictdepth_iterator_t iter_depth;
+
+ iter_depth = xcb_render_pictscreen_depths_iterator(iter_pictscreen.data);
+ for (; iter_depth.rem; xcb_render_pictdepth_next(&iter_depth))
+ {
+ xcb_render_pictvisual_iterator_t iter_visual;
+
+ iter_visual = xcb_render_pictdepth_visuals_iterator(iter_depth.data);
+ for (; iter_visual.rem; xcb_render_pictvisual_next(&iter_visual))
+ {
+ if ((iter_visual.data->visual == visual) &&
+ (pict_format == iter_visual.data->format))
+ {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ free(rep_pictformat);
+#endif /* ECORE_XCB_RENDER */
+
+ return ret;
+}
+
+
+
+
+/**
+ * Set if a window should be ignored.
+ * @param window The given window.
+ * @param ignore if to ignore
+ */
+EAPI void
+ecore_x_window_ignore_set(Ecore_X_Window window,
+ int ignore)
+{
+ int i, j;
+
+ if (ignore)
+ {
+ if (ignore_list)
+ {
+ for (i = 0; i < ignore_num; i++)
+ {
+ if (window == ignore_list[i])
+ return;
+ }
+ ignore_list = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
+ if (!ignore_list) return;
+ ignore_list[ignore_num++] = window;
+ }
+ else
+ {
+ ignore_num = 0;
+ ignore_list = malloc(sizeof(Ecore_X_Window));
+ ignore_list[ignore_num++] = window;
+ }
+ }
+ else
+ {
+ if (!ignore_list) return;
+ for (i = 0, j = 0; i < ignore_num; i++)
+ {
+ if (window != ignore_list[i])
+ ignore_list[i] = ignore_list[j++];
+ else
+ ignore_num--;
+ }
+ ignore_list = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
+ }
+}
+
+/**
+ * Get the ignore list
+ * @param num number of windows in the list
+ * @return list of windows to ignore
+ */
+EAPI Ecore_X_Window *
+ecore_x_window_ignore_list(int *num)
+{
+ if (num) *num = ignore_num;
+ return ignore_list;
+}
+
+/**
+ * Retrieves the size of the given window.
+ * @param win The given window.
+ * @param w Pointer to an integer into which the width is to be stored.
+ * @param h Pointer to an integer into which the height is to be stored.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request,
+ * then ecore_x_drawable_geometry_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_size_get(Ecore_X_Window window,
+ int *width,
+ int *height)
+{
+ if (window == 0)
+ window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ecore_x_drawable_geometry_get(window, NULL, NULL, width, height);
+}
+
+/**
+ * Retrieves the geometry of the given window.
+ * @param win The given window.
+ * @param x Pointer to an integer in which the X position is to be stored.
+ * @param y Pointer to an integer in which the Y position is to be stored.
+ * @param w Pointer to an integer in which the width is to be stored.
+ * @param h Pointer to an integer in which the height is to be stored.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request,
+ * then ecore_x_drawable_geometry_get_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_geometry_get(Ecore_X_Window window,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+ if (!window)
+ window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+
+ ecore_x_drawable_geometry_get(window, x, y, width, height);
+}
+
+/**
+ * Retrieves the width of the border of the given window.
+ * @param win The given window.
+ * @return Width of the border of @p win.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI int
+ecore_x_window_border_width_get(Ecore_X_Window win)
+{
+ /* doesn't make sense to call this on a root window */
+ if (!win)
+ return 0;
+
+ return ecore_x_drawable_border_width_get(win);
+}
+
+/**
+ * Retrieves the depth of the given window.
+ * @param win The given window.
+ * @return Depth of the window.
+ */
+EAPI int
+ecore_x_window_depth_get(Ecore_X_Window win)
+{
+ return ecore_x_drawable_depth_get(win);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ecore_xcb_private.h"
+#include "Ecore_X_Atoms.h"
+
+
+/*
+ * Set CARD32 (array) property
+ */
+EAPI void
+ecore_x_window_prop_card32_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ unsigned int *val,
+ unsigned int num)
+{
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
+ atom, ECORE_X_ATOM_CARDINAL, 32, num, (const void *)val);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @param atom The atom.
+ */
+EAPI void
+ecore_x_window_prop_card32_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window,
+ atom,
+ ECORE_X_ATOM_CARDINAL,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_prop_card32_get_prefetch().
+ */
+EAPI void
+ecore_x_window_prop_card32_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/*
+ * Get CARD32 (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_card32_get(Ecore_X_Window win __UNUSED__,
+ Ecore_X_Atom atom __UNUSED__,
+ unsigned int *val,
+ unsigned int len)
+{
+ xcb_get_property_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply ||
+ (reply->type != ECORE_X_ATOM_CARDINAL) ||
+ (reply->format != 32))
+ return -1;
+
+ if (reply->value_len < len)
+ len = xcb_get_property_value_length(reply);
+
+ if (val)
+ memcpy(val, xcb_get_property_value(reply), len);
+
+ return (int)len;
+}
+
+/*
+ * Get CARD32 (array) property of any length
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_card32_list_get(Ecore_X_Window win __UNUSED__,
+ Ecore_X_Atom atom __UNUSED__,
+ unsigned int **plist)
+{
+ xcb_get_property_reply_t *reply;
+ int num = -1;
+
+ if (plist)
+ *plist = NULL;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return -1;
+
+ if ((reply->type == XCB_NONE) ||
+ (reply->value_len == 0))
+ num = 0;
+ else if ((reply->type == ECORE_X_ATOM_CARDINAL) &&
+ (reply->format == 32))
+ {
+ uint32_t *val;
+
+ num = xcb_get_property_value_length(reply);
+ if (plist)
+ {
+ val = (uint32_t *)malloc (num);
+ if (!val)
+ goto error;
+
+ memcpy(val, xcb_get_property_value(reply), num);
+ *plist = val;
+ }
+ }
+
+ error:
+
+ return num;
+}
+
+/*
+ * Set X ID (array) property
+ */
+EAPI void
+ecore_x_window_prop_xid_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID *xids,
+ unsigned int num)
+{
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
+ atom, type, 32, num, xids);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @param atom The atom.
+ * @param type The atom type.
+ */
+EAPI void
+ecore_x_window_prop_xid_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window,
+ atom,
+ type,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_prop_xid_get_prefetch().
+ */
+EAPI void
+ecore_x_window_prop_xid_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/*
+ * Get X ID (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_xid_get(Ecore_X_Window win __UNUSED__,
+ Ecore_X_Atom atom __UNUSED__,
+ Ecore_X_Atom type __UNUSED__,
+ Ecore_X_ID *xids,
+ unsigned int len)
+{
+ xcb_get_property_reply_t *reply;
+ int num = len;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return -1;
+
+ if (reply->type == XCB_NONE)
+ num = 0;
+ else if (reply->format == 32)
+ {
+ if (reply->value_len < len)
+ num = xcb_get_property_value_length(reply);
+
+ if (xids)
+ memcpy(xids, xcb_get_property_value(reply), num);
+ }
+
+ return num;
+}
+
+/*
+ * Get X ID (array) property
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * The returned array must be freed with free().
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_xid_list_get(Ecore_X_Window win __UNUSED__,
+ Ecore_X_Atom atom __UNUSED__,
+ Ecore_X_Atom type __UNUSED__,
+ Ecore_X_ID **pxids)
+{
+ xcb_get_property_reply_t *reply;
+ int num = -1;
+
+ if (pxids)
+ *pxids = NULL;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return -1;
+
+ if ((reply->type == XCB_NONE) ||
+ (reply->value_len == 0))
+ num = 0;
+ else if ((reply->type == ECORE_X_ATOM_CARDINAL) &&
+ (reply->format == 32))
+ {
+ uint32_t *val;
+
+ num = xcb_get_property_value_length(reply);
+ if (pxids)
+ {
+ val = (uint32_t *)malloc (num);
+ if (!val)
+ return -1;
+
+ memcpy(val, xcb_get_property_value(reply), num);
+ *pxids = val;
+ }
+ }
+
+ return num;
+}
+
+/*
+ * Remove/add/toggle X ID list item.
+ */
+EAPI void
+ecore_x_window_prop_xid_list_change(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom type,
+ Ecore_X_ID item,
+ int op)
+{
+ Ecore_X_ID *lst;
+ int i;
+ int num;
+
+ num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
+ if (num < 0)
+ return; /* Error - assuming invalid window */
+
+ /* Is it there? */
+ for (i = 0; i < num; i++)
+ {
+ if (lst[i] == item)
+ break;
+ }
+
+ if (i < num)
+ {
+ /* Was in list */
+ if (op == ECORE_X_PROP_LIST_ADD)
+ goto done;
+ /* Remove it */
+ num--;
+ for (; i < num; i++)
+ lst[i] = lst[i + 1];
+ }
+ else
+ {
+ /* Was not in list */
+ if (op == ECORE_X_PROP_LIST_REMOVE)
+ goto done;
+ /* Add it */
+ num++;
+ lst = realloc(lst, num * sizeof(Ecore_X_ID));
+ lst[i] = item;
+ }
+
+ ecore_x_window_prop_xid_set(win, atom, type, lst, num);
+
+ done:
+ if (lst)
+ free(lst);
+}
+
+/*
+ * Set Atom (array) property
+ */
+EAPI void
+ecore_x_window_prop_atom_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom *list,
+ unsigned int num)
+{
+ ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @param atom Property atom.
+ */
+EAPI void
+ecore_x_window_prop_atom_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window,
+ atom,
+ ECORE_X_ATOM_ATOM,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_prop_atom_get_prefetch().
+ */
+EAPI void
+ecore_x_window_prop_atom_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/*
+ * Get Atom (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_atom_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom *list,
+ unsigned int len)
+{
+ return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len);
+}
+
+/*
+ * Get Atom (array) property
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * The returned array must be freed with free().
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_atom_list_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom **plist)
+{
+ return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, plist);
+}
+
+/*
+ * Remove/add/toggle atom list item.
+ */
+EAPI void
+ecore_x_window_prop_atom_list_change(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Atom item,
+ int op)
+{
+ ecore_x_window_prop_xid_list_change(win, atom, ECORE_X_ATOM_ATOM, item, op);
+}
+
+/*
+ * Set Window (array) property
+ */
+EAPI void
+ecore_x_window_prop_window_set(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window *list,
+ unsigned int num)
+{
+ ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @param atom The atom.
+ */
+EAPI void
+ecore_x_window_prop_window_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom atom)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window,
+ atom,
+ ECORE_X_ATOM_WINDOW,
+ 0, 0x7fffffff);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_prop_window_get_prefetch().
+ */
+EAPI void
+ecore_x_window_prop_window_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/*
+ * Get Window (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_window_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window *list,
+ unsigned int len)
+{
+ return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_WINDOW, list, len);
+}
+
+/*
+ * Get Window (array) property
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * The returned array must be freed with free().
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_window_list_get(Ecore_X_Window win,
+ Ecore_X_Atom atom,
+ Ecore_X_Window **plist)
+{
+ return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_WINDOW, plist);
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI Ecore_X_Atom
+ecore_x_window_prop_any_type(void)
+{
+ return XCB_GET_PROPERTY_TYPE_ANY;
+}
+
+/**
+ * To be documented.
+ * @param window The window.
+ * @param property The property atom.
+ * @param type The type atom.
+ * @param size The size.
+ * @param data The data.
+ * @param number The size of the data.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI void
+ecore_x_window_prop_property_set(Ecore_X_Window window,
+ Ecore_X_Atom property,
+ Ecore_X_Atom type,
+ int size,
+ void *data,
+ int number)
+{
+ if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
+ property, type,
+ size, number, data);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @param property Property atom.
+ * @param type Type atom.
+ */
+EAPI void
+ecore_x_window_prop_property_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom property,
+ Ecore_X_Atom type)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ property, type, 0, LONG_MAX);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_prop_property_get_prefetch().
+ */
+EAPI void
+ecore_x_window_prop_property_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * To be documented.
+ * @param window The window (Unused).
+ * @param property The property atom (Unused).
+ * @param type The type atom (Unused).
+ * @param size The size (Unused).
+ * @param data The returned data.
+ * @param num The size of the data.
+ * @return 1 on success, 0 otherwise.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI int
+ecore_x_window_prop_property_get(Ecore_X_Window window __UNUSED__,
+ Ecore_X_Atom property __UNUSED__,
+ Ecore_X_Atom type __UNUSED__,
+ int size __UNUSED__,
+ unsigned char **data,
+ int *num)
+{
+ xcb_get_property_reply_t *reply;
+
+ /* make sure these are initialized */
+ if (num) *num = 0L;
+
+ if (data)
+ *data = NULL;
+ else /* we can't store the retrieved data, so just return */
+ return 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return 0;
+
+ if ((reply->format != size) ||
+ (reply->value_len == 0))
+ return 0;
+
+ *data = malloc(reply->value_len);
+ if (!*data)
+ return 0;
+
+ memcpy(*data, xcb_get_property_value(reply),
+ xcb_get_property_value_length(reply));
+
+ if (num)
+ *num = reply->value_len;
+
+ return reply->format;
+}
+
+EAPI void
+ecore_x_window_prop_property_del(Ecore_X_Window window,
+ Ecore_X_Atom property)
+{
+ xcb_delete_property(_ecore_xcb_conn, window, property);
+}
+
+/**
+ * Sends the ListProperties request.
+ * @param window Window whose properties are requested.
+ */
+EAPI void
+ecore_x_window_prop_list_prefetch(Ecore_X_Window window)
+{
+ xcb_list_properties_cookie_t cookie;
+
+ cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, window);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the ListProperties request sent by ecore_x_window_prop_list_prefetch().
+ */
+EAPI void
+ecore_x_window_prop_list_fetch(void)
+{
+ xcb_list_properties_cookie_t cookie;
+ xcb_list_properties_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+
+/**
+ * To be documented.
+ * @param window The window (Unused).
+ * @param num_ret The number of atoms.
+ * @return The returned atoms.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI Ecore_X_Atom *
+ecore_x_window_prop_list(Ecore_X_Window window __UNUSED__,
+ int *num_ret)
+{
+ xcb_list_properties_reply_t *reply;
+ Ecore_X_Atom *atoms;
+
+ if (num_ret) *num_ret = 0;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return NULL;
+
+ atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom));
+ if (!atoms)
+ return NULL;
+ memcpy(atoms,
+ xcb_list_properties_atoms(reply),
+ reply->atoms_len * sizeof(Ecore_X_Atom));
+ if(num_ret)
+ *num_ret = reply->atoms_len;
+
+ return atoms;
+}
+
+/**
+ * Set a window string property.
+ * @param win The window
+ * @param type The property
+ * @param str The string
+ *
+ * Set a window string property
+ */
+EAPI void
+ecore_x_window_prop_string_set(Ecore_X_Window win,
+ Ecore_X_Atom type,
+ const char *str)
+{
+ if (win == 0) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
+ xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
+ type, ECORE_X_ATOM_UTF8_STRING,
+ 8, strlen(str), str);
+}
+
+/**
+ * Sends the GetProperty request.
+ * @param window Window whose properties are requested.
+ * @param type The atom.
+ */
+EAPI void
+ecore_x_window_prop_string_get_prefetch(Ecore_X_Window window,
+ Ecore_X_Atom type)
+{
+ xcb_get_property_cookie_t cookie;
+
+ cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
+ window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
+ type, XCB_GET_PROPERTY_TYPE_ANY, 0L, 1000000L);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+}
+
+
+/**
+ * Gets the reply of the GetProperty request sent by ecore_x_window_prop_string_get_prefetch().
+ */
+EAPI void
+ecore_x_window_prop_string_get_fetch(void)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+}
+
+/**
+ * Get a window string property.
+ * @param window The window
+ * @param type The property
+ *
+ * Return window string property of a window. String must be free'd when done.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_window_prop_string_get_prefetch(), which sends the GetProperty request,
+ * then ecore_x_window_prop_string_get_fetch(), which gets the reply.
+ */
+EAPI char *
+ecore_x_window_prop_string_get(Ecore_X_Window window __UNUSED__,
+ Ecore_X_Atom type __UNUSED__)
+{
+ xcb_get_property_reply_t *reply;
+ char *str = NULL;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ return NULL;
+
+ if (reply->type == ECORE_X_ATOM_UTF8_STRING)
+ {
+ int length;
+
+ length = reply->value_len;
+ str = (char *)malloc(length + 1);
+ memcpy(str,
+ xcb_get_property_value(reply),
+ length);
+ str[length] = '\0';
+ }
+ else
+ {
+ /* FIXME: to be done... */
+
+/* #ifdef X_HAVE_UTF8_STRING */
+/* s = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xtp, */
+/* &list, &items); */
+/* #else */
+/* s = XmbTextPropertyToTextList(_ecore_xcb_conn, &xtp, */
+/* &list, &items); */
+/* #endif */
+/* if ((s == XLocaleNotSupported) || */
+/* (s == XNoMemory) || (s == XConverterNotFound)) */
+/* { */
+/* str = strdup((char *)xtp.value); */
+/* } */
+/* else if ((s >= Success) && (items > 0)) */
+/* { */
+/* str = strdup(list[0]); */
+/* } */
+/* if (list) */
+/* XFreeStringList(list); */
+ }
+
+ return str;
+}
+
+/* FIXME : round trips because of GetWMProtocols */
+/* should we rewrite its code ? */
+EAPI int
+ecore_x_window_prop_protocol_isset(Ecore_X_Window window,
+ Ecore_X_WM_Protocol protocol)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_wm_protocols_reply_t protocols;
+ Ecore_X_Atom proto;
+ uint32_t i;
+ uint8_t ret = 0;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return ret;
+
+ proto = _ecore_xcb_atoms_wm_protocols[protocol];
+
+ cookie = xcb_get_wm_protocols(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_PROTOCOLS);
+
+ if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protocols, NULL))
+ return ret;
+
+ for (i = 0; i < protocols.atoms_len; i++)
+ if (protocols.atoms[i] == proto)
+ {
+ ret = 1;
+ break;
+ }
+
+ xcb_get_wm_protocols_reply_wipe(&protocols);
+
+ return ret;
+}
+
+/**
+ * To be documented.
+ * @param window The window.
+ * @param num_ret The number of WM protocols.
+ * @return The returned WM protocols.
+ *
+ * FIXME: To be fixed.
+ */
+
+/* FIXME : round trips because of get_wm_protocols */
+/* should we rewrite its code ? */
+
+EAPI Ecore_X_WM_Protocol *
+ecore_x_window_prop_protocol_list_get(Ecore_X_Window window,
+ int *num_ret)
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_wm_protocols_reply_t protocols;
+ Ecore_X_WM_Protocol *prot_ret = NULL;
+ uint32_t protos_count;
+ uint32_t i;
+
+ cookie = xcb_get_wm_protocols(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_PROTOCOLS);
+
+ if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protocols, NULL))
+ return NULL;
+
+ if ((protocols.atoms_len <= 0)) return NULL;
+
+ prot_ret = calloc(1, protocols.atoms_len * sizeof(Ecore_X_WM_Protocol));
+ if (!prot_ret)
+ {
+ xcb_get_wm_protocols_reply_wipe(&protocols);
+ return NULL;
+ }
+ for (i = 0; i < protocols.atoms_len; i++)
+ {
+ Ecore_X_WM_Protocol j;
+
+ prot_ret[i] = -1;
+ for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
+ {
+ if (_ecore_xcb_atoms_wm_protocols[j] == protocols.atoms[i])
+ prot_ret[i] = j;
+ }
+ }
+ xcb_get_wm_protocols_reply_wipe(&protocols);
+ *num_ret = protos_count;
+
+ return prot_ret;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/* #include "Ecore.h" */
+#include "ecore_xcb_private.h"
+#include "Ecore_X.h"
+
+
+typedef struct _Shadow Shadow;
+struct _Shadow
+{
+ Shadow *parent;
+ Shadow **children;
+ Ecore_X_Window win;
+ int children_num;
+ short x, y;
+ unsigned short w, h;
+};
+
+static int shadow_count = 0;
+static Shadow **shadow_base = NULL;
+static int shadow_num = 0;
+
+
+/* FIXME: round trips */
+static Shadow *
+_ecore_x_window_tree_walk(Ecore_X_Window window)
+{
+ Shadow *s;
+ Shadow **sl;
+ xcb_get_window_attributes_reply_t *reply_attr;
+ xcb_get_geometry_reply_t *reply_geom;
+ xcb_query_tree_reply_t *reply_tree;
+ xcb_get_window_attributes_cookie_t cookie_attr;
+ xcb_get_geometry_cookie_t cookie_geom;
+ xcb_query_tree_cookie_t cookie_tree;
+ int i;
+ int j;
+
+ cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
+ cookie_geom = xcb_get_geometry_unchecked(_ecore_xcb_conn, window);
+ cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, window);
+
+ reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL);
+ if (!reply_attr)
+ {
+ reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
+ if (reply_geom) free(reply_geom);
+ reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL);
+ if (reply_tree) free(reply_tree);
+ return NULL;
+ }
+
+ if (reply_attr->map_state != XCB_MAP_STATE_VIEWABLE)
+ {
+ reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
+ if (reply_geom) free(reply_geom);
+ reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL);
+ if (reply_tree) free(reply_tree);
+ return NULL;
+ }
+
+ free(reply_attr);
+
+ s = calloc(1, sizeof(Shadow));
+ if (!s) return NULL;
+
+ reply_geom = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_geom, NULL);
+ if (!reply_geom)
+ {
+ reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL);
+ if (reply_tree) free(reply_tree);
+ return NULL;
+ }
+
+ s->win = window;
+ s->x = reply_geom->x;
+ s->y = reply_geom->y;
+ s->w = reply_geom->width;
+ s->h = reply_geom->height;
+
+ free(reply_geom);
+
+ reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL);
+ if (reply_tree)
+/* if (XQueryTree(_ecore_xcb_conn, s->win, &root_win, &parent_win, */
+/* &list, &num)) */
+ {
+ xcb_window_t *list;
+ int num;
+
+ num = xcb_query_tree_children_length(reply_tree);
+ list = xcb_query_tree_children(reply_tree);
+
+ s->children = calloc(1, sizeof(Shadow *) * num);
+ if (s->children)
+ {
+ s->children_num = num;
+ for (i = 0; i < num; i++)
+ {
+ s->children[i] = _ecore_x_window_tree_walk(list[i]);
+ if (s->children[i]) s->children[i]->parent = s;
+ }
+ /* compress list down */
+ j = 0;
+ for (i = 0; i < num; i++)
+ {
+ if (s->children[i])
+ {
+ s->children[j] = s->children[i];
+ j++;
+ }
+ }
+ if (j == 0)
+ {
+ free(s->children);
+ s->children = NULL;
+ s->children_num = 0;
+ }
+ else
+ {
+ s->children_num = j;
+ sl = realloc(s->children, sizeof(Shadow *) * j);
+ if (sl) s->children = sl;
+ }
+ }
+ free(reply_tree);
+ }
+ return s;
+}
+
+static void
+_ecore_x_window_tree_shadow_free1(Shadow *s)
+{
+ int i;
+
+ if (!s) return;
+ if (s->children)
+ {
+ for (i = 0; i < s->children_num; i++)
+ {
+ if (s->children[i])
+ _ecore_x_window_tree_shadow_free1(s->children[i]);
+ }
+ free(s->children);
+ }
+ free(s);
+}
+
+static void
+_ecore_x_window_tree_shadow_free(void)
+{
+ int i;
+
+ if (!shadow_base) return;
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+ _ecore_x_window_tree_shadow_free1(shadow_base[i]);
+ }
+ free(shadow_base);
+ shadow_base = NULL;
+ shadow_num = 0;
+}
+
+static void
+_ecore_x_window_tree_shadow_populate(void)
+{
+ Ecore_X_Window *roots;
+ int i, num;
+
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ shadow_base = calloc(1, sizeof(Shadow *) * num);
+ if (shadow_base)
+ {
+ shadow_num = num;
+ for (i = 0; i < num; i++)
+ shadow_base[i] = _ecore_x_window_tree_walk(roots[i]);
+ }
+ free(roots);
+ }
+}
+
+static void
+_ecore_x_window_tree_shadow_start(void)
+{
+ shadow_count++;
+ if (shadow_count > 1) return;
+ _ecore_x_window_tree_shadow_populate();
+}
+
+static void
+_ecore_x_window_tree_shadow_stop(void)
+{
+ shadow_count--;
+ if (shadow_count != 0) return;
+ _ecore_x_window_tree_shadow_free();
+}
+
+Shadow *
+_ecore_x_window_shadow_tree_find_shadow(Shadow *s, Ecore_X_Window win)
+{
+ Shadow *ss;
+ int i;
+
+ if (s->win == win) return s;
+ if (s->children)
+ {
+ for (i = 0; i < s->children_num; i++)
+ {
+ if (!s->children[i]) continue;
+ if ((ss = _ecore_x_window_shadow_tree_find_shadow(s->children[i], win)))
+ return ss;
+ }
+ }
+ return NULL;
+}
+
+Shadow *
+_ecore_x_window_shadow_tree_find(Ecore_X_Window base)
+{
+ Shadow *s;
+ int i;
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+ if ((s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], base)))
+ return s;
+ }
+ return NULL;
+}
+
+static Ecore_X_Window
+_ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow *s, int bx, int by, int x, int y,
+ Ecore_X_Window *skip, int skip_num)
+{
+ Ecore_X_Window child;
+ int i, j;
+ int wx, wy;
+
+ wx = s->x + bx;
+ wy = s->y + by;
+ if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h))))
+ return 0;
+ if (s->children)
+ {
+ int skipit = 0;
+
+ for (i = s->children_num - 1; i >= 0; --i)
+ {
+ if (!s->children[i]) continue;
+ skipit = 0;
+ if (skip)
+ {
+ for (j = 0; j < skip_num; j++)
+ {
+ if (s->children[i]->win == skip[j])
+ {
+ skipit = 1;
+ goto onward;
+ }
+ }
+ }
+ onward:
+ if (!skipit)
+ {
+ if ((child = _ecore_x_window_shadow_tree_at_xy_get_shadow(s->children[i], wx, wy, x, y, skip, skip_num)))
+ {
+ return child;
+ }
+ }
+ }
+ }
+ return s->win;
+}
+
+static Ecore_X_Window
+_ecore_x_window_shadow_tree_at_xy_get(Ecore_X_Window base, int bx, int by, int x, int y,
+ Ecore_X_Window *skip, int skip_num)
+{
+ Shadow *s;
+
+ if (!shadow_base)
+ {
+ _ecore_x_window_tree_shadow_populate();
+ if (!shadow_base) return 0;
+ }
+ s = _ecore_x_window_shadow_tree_find(base);
+ if (!s) return 0;
+ return _ecore_x_window_shadow_tree_at_xy_get_shadow(s, bx, by, x, y, skip, skip_num);
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but skips the windows in the list. This uses a shadow tree built from the
+ * window tree that is only updated the first time
+ * ecore_x_window_shadow_tree_at_xy_with_skip_get() is called, or the next time
+ * it is called after a ecore_x_window_shadow_tree_flush()
+ * @param base The base window to start searching from (normally root).
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base, int x, int y, Ecore_X_Window *skip, int skip_num)
+{
+ return _ecore_x_window_shadow_tree_at_xy_get(base, 0, 0, x, y, skip, skip_num);
+}
+
+/**
+ * Retrieves the parent window a given window has. This uses the shadow window
+ * tree.
+ * @param root The root window of @p win - if 0, this will be automatically determined with extra processing overhead
+ * @param win The window to get the parent window of
+ * @return The parent window of @p win
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_shadow_parent_get(Ecore_X_Window root, Ecore_X_Window win)
+{
+ Shadow *s;
+ int i;
+
+ if (!shadow_base)
+ {
+ _ecore_x_window_tree_shadow_populate();
+ if (!shadow_base) return 0;
+ }
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+ s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], win);
+ if (s)
+ {
+ if (!s->parent) return 0;
+ return s->parent->win;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Flushes the window shadow tree so nothing is stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_shadow_tree_flush(void)
+{
+ _ecore_x_window_tree_shadow_free();
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#include "ecore_xcb_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Xinerama_Group X Xinerama Extension Functions
+ *
+ * Functions related to the X Xinerama extension.
+ */
+
+
+#ifdef ECORE_XCB_XINERAMA
+static int _xinerama_available = 0;
+static xcb_xinerama_query_version_cookie_t _ecore_xcb_xinerama_init_cookie;
+#endif /* ECORE_XCB_XINERAMA */
+
+
+/* To avoid round trips, the initialization is separated in 2
+ functions: _ecore_xcb_xinerama_init and
+ _ecore_xcb_xinerama_init_finalize. The first one gets the cookies and
+ the second one gets the replies. */
+
+void
+_ecore_x_xinerama_init(const xcb_query_extension_reply_t *reply)
+{
+#ifdef ECORE_XCB_XINERAMA
+ if (reply && (reply->present))
+ _ecore_xcb_xinerama_init_cookie = xcb_xinerama_query_version_unchecked(_ecore_xcb_conn, 1, 2);
+#endif /* ECORE_XCB_XINERAMA */
+}
+
+void
+_ecore_x_xinerama_init_finalize(void)
+{
+#ifdef ECORE_XCB_XINERAMA
+ xcb_xinerama_query_version_reply_t *reply;
+
+ reply = xcb_xinerama_query_version_reply(_ecore_xcb_conn,
+ _ecore_xcb_xinerama_init_cookie, NULL);
+
+ if (reply)
+ {
+ if ((reply->major >= 1) &&
+ (reply->minor >= 1))
+ _xinerama_available = 1;
+ free(reply);
+ }
+#endif /* ECORE_XCB_XINERAMA */
+}
+
+
+/**
+ * Return whether the X server supports the Xinerama Extension.
+ * @return 1 if the X Xinerama Extension is available, 0 otherwise.
+ *
+ * Return 1 if the X server supports the Fixes Xinerama version 1.1,
+ * 0 otherwise.
+ * @ingroup Ecore_X_Xinerama_Group
+ */
+EAPI int
+ecore_x_xinerama_query(void)
+{
+#ifdef ECORE_XCB_XINERAMA
+ return _xinerama_available;
+#else
+ return 0;
+#endif /* ECORE_XCB_XINERAMA */
+}
+
+
+/**
+ * Sends the XineramaQueryScreens request.
+ * @ingroup Ecore_X_Xinerama_Group
+ */
+EAPI void
+ecore_x_xinerama_query_screens_prefetch(void)
+{
+#ifdef ECORE_XCB_XINERAMA
+ xcb_xinerama_query_screens_cookie_t cookie;
+
+ cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn);
+ _ecore_xcb_cookie_cache(cookie.sequence);
+#endif /* ECORE_XCB_XINERAMA */
+}
+
+
+/**
+ * Gets the reply of the XineramaQueryScreens request sent by ecore_x_xinerama_query_screens_prefetch().
+ * @ingroup Ecore_X_Xinerama_Group
+ */
+EAPI void
+ecore_x_xinerama_query_screens_fetch(void)
+{
+#ifdef ECORE_XCB_XINERAMA
+ xcb_xinerama_query_screens_cookie_t cookie;
+ xcb_xinerama_query_screens_reply_t *reply;
+
+ cookie.sequence = _ecore_xcb_cookie_get();
+ reply = xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL);
+ _ecore_xcb_reply_cache(reply);
+#endif /* ECORE_XCB_XINERAMA */
+}
+
+
+/**
+ * Return the number of screens.
+ * @return The screen count.
+ *
+ * Return the number of screens.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request,
+ * then ecore_x_xinerama_query_screens_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Xinerama_Group
+ */
+EAPI int
+ecore_x_xinerama_screen_count_get(void)
+{
+ int screen_count = 0;
+#ifdef ECORE_XCB_XINERAMA
+ xcb_xinerama_screen_info_iterator_t iter;
+ xcb_xinerama_query_screens_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply) return 0;
+
+ iter = xcb_xinerama_query_screens_screen_info_iterator(reply);
+ screen_count = iter.rem;
+#endif /* ECORE_XCB_XINERAMA */
+
+ return screen_count;
+}
+
+
+/**
+ * Get the geometry of the screen.
+ * @param screen The screen (Unused).
+ * @param x The X coordinate of the screen.
+ * @param y The Y coordinate of the screen
+ * @param width The width of the screen
+ * @param height The height of the screen
+ * @return 1 on success, 0 otherwise.
+ *
+ * Get the geometry of the screen whose number is @p screen. The
+ * returned values are stored in @p x, @p y, @p width and @p height.
+ *
+ * To use this function, you must call before, and in order,
+ * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request,
+ * then ecore_x_xinerama_query_screens_fetch(), which gets the reply.
+ * @ingroup Ecore_X_Xinerama_Group
+ */
+EAPI int
+ecore_x_xinerama_screen_geometry_get(int screen,
+ int *x,
+ int *y,
+ int *width,
+ int *height)
+{
+#ifdef ECORE_XCB_XINERAMA
+ xcb_xinerama_screen_info_iterator_t iter;
+ xcb_xinerama_query_screens_reply_t *reply;
+
+ reply = _ecore_xcb_reply_get();
+ if (!reply)
+ {
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels;
+ if (height) *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels;
+
+ return 0;
+ }
+
+ iter = xcb_xinerama_query_screens_screen_info_iterator(reply);
+ for (; iter.rem; screen--, xcb_xinerama_screen_info_next(&iter))
+ {
+ if (screen == 0)
+ {
+ if (x) *x = iter.data->x_org;
+ if (y) *y = iter.data->y_org;
+ if (width) *width = iter.data->width;
+ if (height) *height = iter.data->height;
+ return 1;
+ }
+ }
+#endif /* ECORE_XCB_XINERAMA */
+
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (width) *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels;
+ if (height) *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels;
+
+ return 0;
+}
--- /dev/null
+.deps
+.libs
+Makefile
+Makefile.in
+*.lo
+libecore_x_xlib.la
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ECORE_X_XLIB
+
+AM_CPPFLAGS = \
+@Xcursor_cflags@ \
+@XKB_CFLAGS@ \
+@XDAMAGE_CFLAGS@ \
+@XCOMPOSITE_CFLAGS@ \
+@XDPMS_CFLAGS@ \
+@XFIXES_CFLAGS@ \
+@XI2_CFLAGS@ \
+@XINERAMA_CFLAGS@ \
+@XPRINT_CFLAGS@ \
+@XRANDR_CFLAGS@ \
+@XRENDER_CFLAGS@ \
+@XSS_CFLAGS@ \
+@XTEST_CFLAGS@ \
+@x_cflags@ \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_x \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_x \
+-I$(top_builddir)/src/lib/ecore_input \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@
+
+noinst_LTLIBRARIES = libecore_x_xlib.la
+
+libecore_x_xlib_la_SOURCES = \
+ecore_x.c \
+ecore_x_dnd.c \
+ecore_x_sync.c \
+ecore_x_randr.c \
+ecore_x_fixes.c \
+ecore_x_damage.c \
+ecore_x_composite.c \
+ecore_x_error.c \
+ecore_x_events.c \
+ecore_x_icccm.c \
+ecore_x_netwm.c \
+ecore_x_mwm.c \
+ecore_x_e.c \
+ecore_x_selection.c \
+ecore_x_window.c \
+ecore_x_window_prop.c \
+ecore_x_window_shape.c \
+ecore_x_pixmap.c \
+ecore_x_gc.c \
+ecore_x_xinerama.c \
+ecore_x_screensaver.c \
+ecore_x_dpms.c \
+ecore_x_drawable.c \
+ecore_x_cursor.c \
+ecore_x_test.c \
+ecore_x_atoms.c \
+ecore_x_region.c \
+ecore_x_image.c \
+ecore_x_xi2.c
+
+libecore_x_xlib_la_LIBADD = \
+@Xcursor_libs@ \
+@XKB_LIBS@ \
+@XDAMAGE_LIBS@ \
+@XCOMPOSITE_LIBS@ \
+@XDPMS_LIBS@ \
+@XFIXES_LIBS@ \
+@XI2_LIBS@ \
+@XINERAMA_LIBS@ \
+@XPRINT_LIBS@ \
+@XRANDR_LIBS@ \
+@XRENDER_LIBS@ \
+@XSS_LIBS@ \
+@XTEST_LIBS@ \
+@x_libs@ \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+@EINA_LIBS@
+
+libecore_x_xlib_la_LDFLAGS = -version-info @version_info@
+
+endif
+
+EXTRA_DIST = ecore_x_private.h
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+//#define LOGRT 1
+
+#ifdef LOGRT
+#include <dlfcn.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+#include "Ecore_Input.h"
+
+static int _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_x_key_mask_get(KeySym sym);
+static int _ecore_x_event_modifier(unsigned int state);
+
+static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL;
+
+static const int AnyXEvent = 0; /* 0 can be used as there are no event types
+ * with index 0 and 1 as they are used for
+ * errors
+ */
+
+static int _ecore_x_event_shape_id = 0;
+static int _ecore_x_event_screensaver_id = 0;
+static int _ecore_x_event_sync_id = 0;
+int _ecore_xlib_log_dom = -1;
+
+#ifdef ECORE_XRANDR
+static int _ecore_x_event_randr_id = 0;
+#endif
+#ifdef ECORE_XFIXES
+static int _ecore_x_event_fixes_selection_id = 0;
+#endif
+#ifdef ECORE_XDAMAGE
+static int _ecore_x_event_damage_id = 0;
+#endif
+static int _ecore_x_event_handlers_num = 0;
+static void (**_ecore_x_event_handlers) (XEvent * event) = NULL;
+
+static int _ecore_x_init_count = 0;
+static int _ecore_x_grab_count = 0;
+
+Display *_ecore_x_disp = NULL;
+double _ecore_x_double_click_time = 0.25;
+Time _ecore_x_event_last_time = 0;
+Window _ecore_x_event_last_win = 0;
+int _ecore_x_event_last_root_x = 0;
+int _ecore_x_event_last_root_y = 0;
+int _ecore_x_xcursor = 0;
+XIC _ecore_x_ic = NULL; /* Input context for composed characters */
+
+Ecore_X_Window _ecore_x_private_win = 0;
+
+Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
+
+EAPI int ECORE_X_EVENT_ANY = 0;
+EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
+EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
+EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
+EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
+EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
+EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
+EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
+EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
+EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
+EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
+EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
+EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
+EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
+EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
+EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
+EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
+EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
+EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
+EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
+EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0;
+EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0;
+EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0;
+EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
+/*
+EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0;
+EAPI int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 0;
+*/
+
+EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
+EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
+EAPI int ECORE_X_EVENT_PING = 0;
+EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
+
+EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
+EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
+EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
+
+EAPI int ECORE_X_EVENT_GENERIC = 0;
+
+int ECORE_X_MODIFIER_SHIFT = 0;
+int ECORE_X_MODIFIER_CTRL = 0;
+int ECORE_X_MODIFIER_ALT = 0;
+int ECORE_X_MODIFIER_WIN = 0;
+
+EAPI int ECORE_X_LOCK_SCROLL = 0;
+EAPI int ECORE_X_LOCK_NUM = 0;
+EAPI int ECORE_X_LOCK_CAPS = 0;
+
+#ifdef LOGRT
+static double t0 = 0.0;
+static Status (*_logrt_real_reply) (Display *disp, void *rep, int extra, Bool discard) = NULL;
+static void
+_logrt_init(void)
+{
+ void *lib;
+
+ lib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
+ if (!lib) lib = dlopen("libX11.so.6", RTLD_GLOBAL | RTLD_LAZY);
+ if (!lib) lib = dlopen("libX11.so.6.3", RTLD_GLOBAL | RTLD_LAZY);
+ if (!lib) lib = dlopen("libX11.so.6.3.0", RTLD_GLOBAL | RTLD_LAZY);
+ _logrt_real_reply = dlsym(lib, "_XReply");
+ t0 = ecore_time_get();
+}
+Status
+_XReply(Display *disp, void *rep, int extra, Bool discard)
+{
+ void *bt[128];
+ int i, n;
+ char **sym;
+
+ n = backtrace(bt, 128);
+ if (n > 0)
+ {
+ sym = backtrace_symbols(bt, n);
+ printf("ROUNDTRIP: %4.4f :", ecore_time_get() - t0);
+ if (sym)
+ {
+ for (i = n - 1; i > 0; i--)
+ {
+ char *fname = strchr(sym[i], '(');
+ if (fname)
+ {
+ char *tsym = alloca(strlen(fname) + 1);
+ char *end;
+ strcpy(tsym, fname + 1);
+ end = strchr(tsym, '+');
+ if (end)
+ {
+ *end = 0;
+ printf("%s", tsym);
+ }
+ else
+ printf("???");
+ }
+ else
+ printf("???");
+ if (i > 1) printf(" > ");
+ }
+ printf("\n");
+ }
+ }
+ // fixme: logme
+ return _logrt_real_reply(disp, rep, extra, discard);
+}
+#endif
+
+/**
+ * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions
+ *
+ * Functions that start and shut down the Ecore X Library.
+ */
+
+/**
+ * Initialize the X display connection to the given display.
+ *
+ * @param name Display target name. If @c NULL, the default display is
+ * assumed.
+ * @return The number of times the library has been initialized without
+ * being shut down. 0 is returned if an error occurs.
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_init(const char *name)
+{
+ int shape_base = 0;
+ int shape_err_base = 0;
+#ifdef ECORE_XSS
+ int screensaver_base = 0;
+ int screensaver_err_base = 0;
+#endif
+ int sync_base = 0;
+ int sync_err_base = 0;
+#ifdef ECORE_XRANDR
+ int randr_base = 0;
+ int randr_err_base = 0;
+#endif
+#ifdef ECORE_XFIXES
+ int fixes_base = 0;
+ int fixes_err_base = 0;
+#endif
+#ifdef ECORE_XDAMAGE
+ int damage_base = 0;
+ int damage_err_base = 0;
+#endif
+
+ if (++_ecore_x_init_count != 1)
+ return _ecore_x_init_count;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef LOGRT
+ _logrt_init();
+#endif
+
+ _ecore_xlib_log_dom = eina_log_domain_register("EcoreX11", ECORE_XLIB_DEFAULT_LOG_COLOR);
+ if(_ecore_xlib_log_dom < 0)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for the Ecore Xlib module.");
+ return --_ecore_x_init_count;
+ }
+ if (!ecore_event_init())
+ {
+ eina_log_domain_unregister(_ecore_xlib_log_dom);
+ _ecore_xlib_log_dom = -1;
+ return --_ecore_x_init_count;
+ }
+ _ecore_x_disp = XOpenDisplay((char *)name);
+ if (!_ecore_x_disp)
+ goto shutdown_ecore_event;
+
+ _ecore_x_error_handler_init();
+ _ecore_x_event_handlers_num = LASTEvent;
+
+#define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events) \
+ do { \
+ if (_ecore_x_event_handlers_num < (ext_base + ext_num_events)) \
+ _ecore_x_event_handlers_num = (ext_base + ext_num_events); \
+ } while (0)
+
+ if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base))
+ _ecore_x_event_shape_id = shape_base;
+ ECORE_X_EVENT_HANDLERS_GROW(shape_base, ShapeNumberEvents);
+
+#ifdef ECORE_XSS
+ if (XScreenSaverQueryExtension(_ecore_x_disp, &screensaver_base, &screensaver_err_base))
+ _ecore_x_event_screensaver_id = screensaver_base;
+ ECORE_X_EVENT_HANDLERS_GROW(screensaver_base, ScreenSaverNumberEvents);
+#endif
+
+ if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base))
+ {
+ int major, minor;
+
+ _ecore_x_event_sync_id = sync_base;
+ if (!XSyncInitialize(_ecore_x_disp, &major, &minor))
+ _ecore_x_event_sync_id = 0;
+ }
+ ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents);
+
+#ifdef ECORE_XRANDR
+ if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base))
+ _ecore_x_event_randr_id = randr_base;
+ ECORE_X_EVENT_HANDLERS_GROW(randr_base, RRNumberEvents);
+#endif
+
+#ifdef ECORE_XFIXES
+ if (XFixesQueryExtension(_ecore_x_disp, &fixes_base, &fixes_err_base))
+ _ecore_x_event_fixes_selection_id = fixes_base;
+ ECORE_X_EVENT_HANDLERS_GROW(fixes_base, XFixesNumberEvents);
+#endif
+
+#ifdef ECORE_XDAMAGE
+ if (XDamageQueryExtension(_ecore_x_disp, &damage_base, &damage_err_base))
+ _ecore_x_event_damage_id = damage_base;
+ ECORE_X_EVENT_HANDLERS_GROW(damage_base, XDamageNumberEvents);
+#endif
+
+ _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *));
+ if (!_ecore_x_event_handlers)
+ goto close_display;
+
+#ifdef ECORE_XCURSOR
+ _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp);
+#endif
+ _ecore_x_event_handlers[AnyXEvent] = _ecore_x_event_handle_any_event;
+ _ecore_x_event_handlers[KeyPress] = _ecore_x_event_handle_key_press;
+ _ecore_x_event_handlers[KeyRelease] = _ecore_x_event_handle_key_release;
+ _ecore_x_event_handlers[ButtonPress] = _ecore_x_event_handle_button_press;
+ _ecore_x_event_handlers[ButtonRelease] = _ecore_x_event_handle_button_release;
+ _ecore_x_event_handlers[MotionNotify] = _ecore_x_event_handle_motion_notify;
+ _ecore_x_event_handlers[EnterNotify] = _ecore_x_event_handle_enter_notify;
+ _ecore_x_event_handlers[LeaveNotify] = _ecore_x_event_handle_leave_notify;
+ _ecore_x_event_handlers[FocusIn] = _ecore_x_event_handle_focus_in;
+ _ecore_x_event_handlers[FocusOut] = _ecore_x_event_handle_focus_out;
+ _ecore_x_event_handlers[KeymapNotify] = _ecore_x_event_handle_keymap_notify;
+ _ecore_x_event_handlers[Expose] = _ecore_x_event_handle_expose;
+ _ecore_x_event_handlers[GraphicsExpose] = _ecore_x_event_handle_graphics_expose;
+ _ecore_x_event_handlers[VisibilityNotify] = _ecore_x_event_handle_visibility_notify;
+ _ecore_x_event_handlers[CreateNotify] = _ecore_x_event_handle_create_notify;
+ _ecore_x_event_handlers[DestroyNotify] = _ecore_x_event_handle_destroy_notify;
+ _ecore_x_event_handlers[UnmapNotify] = _ecore_x_event_handle_unmap_notify;
+ _ecore_x_event_handlers[MapNotify] = _ecore_x_event_handle_map_notify;
+ _ecore_x_event_handlers[MapRequest] = _ecore_x_event_handle_map_request;
+ _ecore_x_event_handlers[ReparentNotify] = _ecore_x_event_handle_reparent_notify;
+ _ecore_x_event_handlers[ConfigureNotify] = _ecore_x_event_handle_configure_notify;
+ _ecore_x_event_handlers[ConfigureRequest] = _ecore_x_event_handle_configure_request;
+ _ecore_x_event_handlers[GravityNotify] = _ecore_x_event_handle_gravity_notify;
+ _ecore_x_event_handlers[ResizeRequest] = _ecore_x_event_handle_resize_request;
+ _ecore_x_event_handlers[CirculateNotify] = _ecore_x_event_handle_circulate_notify;
+ _ecore_x_event_handlers[CirculateRequest] = _ecore_x_event_handle_circulate_request;
+ _ecore_x_event_handlers[PropertyNotify] = _ecore_x_event_handle_property_notify;
+ _ecore_x_event_handlers[SelectionClear] = _ecore_x_event_handle_selection_clear;
+ _ecore_x_event_handlers[SelectionRequest] = _ecore_x_event_handle_selection_request;
+ _ecore_x_event_handlers[SelectionNotify] = _ecore_x_event_handle_selection_notify;
+ _ecore_x_event_handlers[ColormapNotify] = _ecore_x_event_handle_colormap_notify;
+ _ecore_x_event_handlers[ClientMessage] = _ecore_x_event_handle_client_message;
+ _ecore_x_event_handlers[MappingNotify] = _ecore_x_event_handle_mapping_notify;
+#ifdef GenericEvent
+ _ecore_x_event_handlers[GenericEvent] = _ecore_x_event_handle_generic_event;
+#endif
+
+ if (_ecore_x_event_shape_id)
+ _ecore_x_event_handlers[_ecore_x_event_shape_id] = _ecore_x_event_handle_shape_change;
+ if (_ecore_x_event_screensaver_id)
+ _ecore_x_event_handlers[_ecore_x_event_screensaver_id] = _ecore_x_event_handle_screensaver_notify;
+ if (_ecore_x_event_sync_id)
+ {
+ _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] =
+ _ecore_x_event_handle_sync_counter;
+ _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] =
+ _ecore_x_event_handle_sync_alarm;
+ }
+#ifdef ECORE_XRANDR
+ if (_ecore_x_event_randr_id)
+ {
+ _ecore_x_event_handlers[_ecore_x_event_randr_id + RRScreenChangeNotify] = _ecore_x_event_handle_randr_change;
+ _ecore_x_event_handlers[_ecore_x_event_randr_id + RRNotify] = _ecore_x_event_handle_randr_notify;
+ }
+#endif
+#ifdef ECORE_XFIXES
+ if (_ecore_x_event_fixes_selection_id)
+ _ecore_x_event_handlers[_ecore_x_event_fixes_selection_id] = _ecore_x_event_handle_fixes_selection_notify;
+#endif
+#ifdef ECORE_XDAMAGE
+ if (_ecore_x_event_damage_id)
+ _ecore_x_event_handlers[_ecore_x_event_damage_id] = _ecore_x_event_handle_damage_notify;
+#endif
+#ifdef ECORE_XKB
+ // set x autorepeat detection to on. that means instead of
+ // press-release-press-release-press-release
+ // you get
+ // press-press-press-press-press-release
+ do
+ {
+ Bool works = 0;
+ XkbSetDetectableAutoRepeat(_ecore_x_disp, 1, &works);
+ }
+ while (0);
+#endif
+
+ if (!ECORE_X_EVENT_ANY)
+ {
+ ECORE_X_EVENT_ANY = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
+ ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
+ ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
+ ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
+ ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_RANDR_CRTC_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new();
+ ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new();
+
+ ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
+ /*
+ ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new();
+ */
+
+ ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
+ ECORE_X_EVENT_PING = ecore_event_type_new();
+
+ ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new();
+ ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new();
+ ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new();
+
+ ECORE_X_EVENT_GENERIC = ecore_event_type_new();
+ }
+
+ /* everything has these... unless its like a pda... :) */
+ ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L);
+ ECORE_X_MODIFIER_CTRL = _ecore_x_key_mask_get(XK_Control_L);
+
+ /* apple's xdarwin has no alt!!!! */
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Alt_L);
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Meta_L);
+ if (!ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Super_L);
+
+ /* the windows key... a valid modifier :) */
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Super_L);
+ if (!ECORE_X_MODIFIER_WIN)
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Mode_switch);
+ if (!ECORE_X_MODIFIER_WIN)
+ ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Meta_L);
+
+ if (ECORE_X_MODIFIER_WIN == ECORE_X_MODIFIER_ALT)
+ ECORE_X_MODIFIER_WIN = 0;
+ if (ECORE_X_MODIFIER_ALT == ECORE_X_MODIFIER_CTRL)
+ ECORE_X_MODIFIER_ALT = 0;
+
+ ECORE_X_LOCK_SCROLL = _ecore_x_key_mask_get(XK_Scroll_Lock);
+ ECORE_X_LOCK_NUM = _ecore_x_key_mask_get(XK_Num_Lock);
+ ECORE_X_LOCK_CAPS = _ecore_x_key_mask_get(XK_Caps_Lock);
+
+ _ecore_x_fd_handler_handle =
+ ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp),
+ ECORE_FD_READ,
+ _ecore_x_fd_handler, _ecore_x_disp,
+ _ecore_x_fd_handler_buf, _ecore_x_disp);
+ if (!_ecore_x_fd_handler_handle)
+ goto free_event_handlers;
+
+ _ecore_x_atoms_init();
+
+ /* Set up the ICCCM hints */
+ ecore_x_icccm_init();
+
+ /* Set up the _NET_... hints */
+ ecore_x_netwm_init();
+
+ /* old e hints init */
+ ecore_x_e_init();
+
+ /* This is just to be anal about naming conventions */
+
+ _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = ECORE_X_ATOM_WM_TAKE_FOCUS;
+ _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] = ECORE_X_ATOM_NET_WM_PING;
+ _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+
+ _ecore_x_selection_data_init();
+ _ecore_x_dnd_init();
+ _ecore_x_fixes_init();
+ _ecore_x_damage_init();
+ _ecore_x_composite_init();
+ _ecore_x_dpms_init();
+ _ecore_x_randr_init();
+ _ecore_x_input_init();
+
+ _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456);
+
+#ifdef ENABLE_XIM
+ /* Setup XIM */
+ if (!_ecore_x_ic && XSupportsLocale())
+ {
+ XIM im;
+ XIC ic;
+ XIMStyles *supported_styles;
+ XIMStyle chosen_style = 0;
+ Ecore_X_Window client_window = ecore_x_window_root_get(_ecore_x_private_win);
+ char *ret;
+ int i;
+
+ XSetLocaleModifiers("@im=none");
+ if ((im = XOpenIM(_ecore_x_disp, NULL, NULL, NULL)) == NULL)
+ goto _im_create_end;
+ ret = XGetIMValues(im, XNQueryInputStyle, &supported_styles, NULL);
+ if (ret || !supported_styles)
+ goto _im_create_error;
+ for (i = 0; i < supported_styles->count_styles; i++)
+ if (supported_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
+ chosen_style = supported_styles->supported_styles[i];
+ XFree(supported_styles);
+ if (!chosen_style)
+ goto _im_create_error;
+ ic = XCreateIC(im, XNInputStyle, chosen_style, XNClientWindow, client_window, NULL);
+ if (ic)
+ {
+ _ecore_x_ic = ic;
+ goto _im_create_end;
+ }
+_im_create_error:
+ XCloseIM(im);
+ }
+_im_create_end:
+#endif
+ return _ecore_x_init_count;
+
+ free_event_handlers:
+ free(_ecore_x_event_handlers);
+ _ecore_x_event_handlers = NULL;
+ close_display:
+ XCloseDisplay(_ecore_x_disp);
+ _ecore_x_fd_handler_handle = NULL;
+ _ecore_x_disp = NULL;
+ shutdown_ecore_event:
+ ecore_event_shutdown();
+
+ return --_ecore_x_init_count;
+}
+
+static int
+_ecore_x_shutdown(int close_display)
+{
+ if (--_ecore_x_init_count != 0)
+ return _ecore_x_init_count;
+
+ if (!_ecore_x_disp) return _ecore_x_init_count;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+#ifdef ENABLE_XIM
+ if (_ecore_x_ic)
+ {
+ XIM xim;
+ xim = XIMOfIC(_ecore_x_ic);
+ XDestroyIC(_ecore_x_ic);
+ XCloseIM(xim);
+ _ecore_x_ic = NULL;
+ }
+#endif
+ if (close_display)
+ XCloseDisplay(_ecore_x_disp);
+ else
+ close(ConnectionNumber(_ecore_x_disp));
+ free(_ecore_x_event_handlers);
+ ecore_main_fd_handler_del(_ecore_x_fd_handler_handle);
+ _ecore_x_fd_handler_handle = NULL;
+ _ecore_x_disp = NULL;
+ _ecore_x_event_handlers = NULL;
+ _ecore_x_input_shutdown();
+ _ecore_x_selection_shutdown();
+ _ecore_x_dnd_shutdown();
+ ecore_x_netwm_shutdown();
+ ecore_event_shutdown();
+ eina_log_domain_unregister(_ecore_xlib_log_dom);
+ _ecore_xlib_log_dom = -1;
+ return _ecore_x_init_count;
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * In shutting down the library, the X display connection is terminated
+ * and any event handlers for it are removed.
+ *
+ * @return The number of times the library has been initialized without
+ * being shut down.
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_shutdown(void)
+{
+ return _ecore_x_shutdown(1);
+}
+
+/**
+ * Shuts down the Ecore X library.
+ *
+ * As ecore_x_shutdown, except do not close Display, only connection.
+ *
+ * @ingroup Ecore_X_Init_Group
+ */
+EAPI int
+ecore_x_disconnect(void)
+{
+ return _ecore_x_shutdown(0);
+}
+
+/**
+ * @defgroup Ecore_X_Display_Attr_Group X Display Attributes
+ *
+ * Functions that set and retrieve X display attributes.
+ */
+
+/**
+ * Retrieves the Ecore_X_Display handle used for the current X connection.
+ * @return The current X display.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+EAPI Ecore_X_Display *
+ecore_x_display_get(void)
+{
+ return (Ecore_X_Display *)_ecore_x_disp;
+}
+
+/**
+ * Retrieves the X display file descriptor.
+ * @return The current X display file descriptor.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+EAPI int
+ecore_x_fd_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ConnectionNumber(_ecore_x_disp);
+}
+
+/**
+ * Retrieves the Ecore_X_Screen handle used for the current X connection.
+ * @return The current default screen.
+ * @ingroup Ecore_Xcb_Display_Attr_Group
+ */
+EAPI Ecore_X_Screen*
+ecore_x_default_screen_get(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return (Ecore_X_Screen*) DefaultScreenOfDisplay(_ecore_x_disp);
+}
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+EAPI void
+ecore_x_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_x_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_x_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ * @ingroup Ecore_X_Display_Attr_Group
+ */
+EAPI double
+ecore_x_double_click_time_get(void)
+{
+ return _ecore_x_double_click_time;
+}
+
+/**
+ * @defgroup Ecore_X_Flush_Group X Synchronization Functions
+ *
+ * Functions that ensure that all commands that have been issued by the
+ * Ecore X library have been sent to the server.
+ */
+
+/**
+ * Sends all X commands in the X Display buffer.
+ * @ingroup Ecore_X_Flush_Group
+ */
+EAPI void
+ecore_x_flush(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFlush(_ecore_x_disp);
+}
+
+/**
+ * Flushes the command buffer and waits until all requests have been
+ * processed by the server.
+ * @ingroup Ecore_X_Flush_Group
+ */
+EAPI void
+ecore_x_sync(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSync(_ecore_x_disp, False);
+}
+
+/**
+ * Kill all clients with subwindows under a given window.
+ *
+ * You can kill all clients connected to the X server by using
+ * @ref ecore_x_window_root_list to get a list of root windows, and
+ * then passing each root window to this function.
+ *
+ * @param root The window whose children will be killed.
+ */
+EAPI void
+ecore_x_killall(Ecore_X_Window root)
+{
+ unsigned int j;
+ Window root_r;
+ Window parent_r;
+ Window *children_r = NULL;
+ unsigned int num_children = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGrabServer(_ecore_x_disp);
+ /* Tranverse window tree starting from root, and drag each
+ * before the firing squad */
+ while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r,
+ &children_r, &num_children) && (num_children > 0))
+ {
+ for (j = 0; j < num_children; ++j)
+ {
+ XKillClient(_ecore_x_disp, children_r[j]);
+ }
+
+ XFree(children_r);
+ }
+ XUngrabServer(_ecore_x_disp);
+ XSync(_ecore_x_disp, False);
+}
+
+/**
+ * Kill a specific client
+ *
+ * You can kill a specific client owning window @p win
+ *
+ * @param win Window of the client to be killed
+ */
+EAPI void
+ecore_x_kill(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XKillClient(_ecore_x_disp, win);
+}
+
+/**
+ * Return the last event time
+ */
+EAPI Ecore_X_Time
+ecore_x_current_time_get(void)
+{
+ return _ecore_x_event_last_time;
+}
+
+/**
+ * Return the screen DPI
+ *
+ * This is a simplistic call to get DPI. It does not account for differing
+ * DPI in the x amd y axes nor does it accoutn for multihead or xinerama and
+ * xrander where different parts of the screen may have differen DPI etc.
+ *
+ * @return the general screen DPI (dots/pixels per inch).
+ */
+EAPI int
+ecore_x_dpi_get(void)
+{
+ Screen *s;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ s = DefaultScreenOfDisplay(_ecore_x_disp);
+ if (s->mwidth <= 0) return 75;
+ return (((s->width * 254) / s->mwidth) + 5) / 10;
+}
+
+static int
+_ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Display *d;
+
+ d = data;
+ while (XPending(d))
+ {
+ XEvent ev;
+
+ XNextEvent(d, &ev);
+
+#ifdef ENABLE_XIM
+ /* Filter event for XIM */
+ if (XFilterEvent(&ev, ev.xkey.window)) continue;
+#endif
+
+ if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num))
+ {
+ if (_ecore_x_event_handlers[AnyXEvent])
+ _ecore_x_event_handlers[AnyXEvent] (&ev);
+
+ if (_ecore_x_event_handlers[ev.type])
+ _ecore_x_event_handlers[ev.type] (&ev);
+ }
+ }
+ return 1;
+}
+
+static int
+_ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+{
+ Display *d;
+
+ d = data;
+ if (XPending(d)) return 1;
+ return 0;
+}
+
+static int
+_ecore_x_key_mask_get(KeySym sym)
+{
+ XModifierKeymap *mod;
+ KeySym sym2;
+ int i, j;
+ const int masks[8] =
+ {
+ ShiftMask, LockMask, ControlMask,
+ Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
+ };
+
+ mod = XGetModifierMapping(_ecore_x_disp);
+ if ((mod) && (mod->max_keypermod > 0))
+ {
+ for (i = 0; i < (8 * mod->max_keypermod); i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ sym2 = XKeycodeToKeysym(_ecore_x_disp, mod->modifiermap[i], j);
+ if (sym2 != 0) break;
+ }
+ if (sym2 == sym)
+ {
+ int mask;
+
+ mask = masks[i / mod->max_keypermod];
+ if (mod->modifiermap) XFree(mod->modifiermap);
+ XFree(mod);
+ return mask;
+ }
+ }
+ }
+ if (mod)
+ {
+ if (mod->modifiermap) XFree(mod->modifiermap);
+ XFree(mod);
+ }
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+/* FIXME: these funcs need categorising */
+/*****************************************************************************/
+
+/**
+ * Get a list of all the root windows on the server.
+ *
+ * @note The returned array will need to be freed after use.
+ * @param num_ret Pointer to integer to put number of windows returned in.
+ * @return An array of all the root windows. @c NULL is returned if memory
+ * could not be allocated for the list, or if @p num_ret is @c NULL.
+ */
+EAPI Ecore_X_Window *
+ecore_x_window_root_list(int *num_ret)
+{
+ int num, i;
+ Ecore_X_Window *roots;
+#ifdef ECORE_XPRINT
+ int xp_base, xp_err_base;
+#endif
+
+ if (!num_ret) return NULL;
+ *num_ret = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef ECORE_XPRINT
+ num = ScreenCount(_ecore_x_disp);
+ if (XpQueryExtension(_ecore_x_disp, &xp_base, &xp_err_base))
+ {
+ Screen **ps = NULL;
+ int psnum = 0;
+
+ ps = XpQueryScreens(_ecore_x_disp, &psnum);
+ if (ps)
+ {
+ int overlap, j;
+
+ overlap = 0;
+ for (i = 0; i < num; i++)
+ {
+ for (j = 0; j < psnum; j++)
+ {
+ if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
+ overlap++;
+ }
+ }
+ roots = malloc((num - overlap) * sizeof(Window));
+ if (roots)
+ {
+ int k;
+
+ k = 0;
+ for (i = 0; i < num; i++)
+ {
+ int is_print;
+
+ is_print = 0;
+ for (j = 0; j < psnum; j++)
+ {
+ if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j])
+ {
+ is_print = 1;
+ break;
+ }
+ }
+ if (!is_print)
+ {
+ roots[k] = RootWindow(_ecore_x_disp, i);
+ k++;
+ }
+ }
+ *num_ret = k;
+ }
+ XFree(ps);
+ }
+ else
+ {
+ roots = malloc(num * sizeof(Window));
+ if (!roots) return NULL;
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+ }
+ }
+ else
+ {
+ roots = malloc(num * sizeof(Window));
+ if (!roots) return NULL;
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+ }
+#else
+ num = ScreenCount(_ecore_x_disp);
+ roots = malloc(num * sizeof(Window));
+ if (!roots) return NULL;
+ *num_ret = num;
+ for (i = 0; i < num; i++)
+ roots[i] = RootWindow(_ecore_x_disp, i);
+#endif
+ return roots;
+}
+
+EAPI Ecore_X_Window
+ecore_x_window_root_first_get(void)
+{
+ return RootWindow(_ecore_x_disp, 0);
+/*
+ int num;
+ Ecore_X_Window root, *roots = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ roots = ecore_x_window_root_list(&num);
+ if (!(roots)) return 0;
+
+ if (num > 0)
+ root = roots[0];
+ else
+ root = 0;
+
+ free(roots);
+ return root;
+ */
+}
+
+
+static void _ecore_x_window_manage_error(void *data);
+
+static int _ecore_x_window_manage_failed = 0;
+static void
+_ecore_x_window_manage_error(void *data __UNUSED__)
+{
+ if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) &&
+ (ecore_x_error_code_get() == BadAccess))
+ _ecore_x_window_manage_failed = 1;
+}
+
+EAPI int
+ecore_x_window_manage(Ecore_X_Window win)
+{
+ XWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True) return 0;
+ ecore_x_sync();
+ _ecore_x_window_manage_failed = 0;
+ ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL);
+ XSelectInput(_ecore_x_disp, win,
+ EnterWindowMask |
+ LeaveWindowMask |
+ PropertyChangeMask |
+ ResizeRedirectMask |
+ SubstructureRedirectMask |
+ SubstructureNotifyMask |
+ StructureNotifyMask |
+ KeyPressMask |
+ KeyReleaseMask |
+ att.your_event_mask);
+ ecore_x_sync();
+ ecore_x_error_handler_set(NULL, NULL);
+ if (_ecore_x_window_manage_failed)
+ {
+ _ecore_x_window_manage_failed = 0;
+ return 0;
+ }
+ return 1;
+}
+
+EAPI void
+ecore_x_window_container_manage(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ SubstructureRedirectMask |
+ SubstructureNotifyMask);
+}
+
+EAPI void
+ecore_x_window_client_manage(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+// ResizeRedirectMask |
+ FocusChangeMask |
+ ColormapChangeMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ SubstructureNotifyMask
+ );
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+}
+
+EAPI void
+ecore_x_window_sniff(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+ SubstructureNotifyMask);
+}
+
+EAPI void
+ecore_x_window_client_sniff(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSelectInput(_ecore_x_disp, win,
+ PropertyChangeMask |
+ FocusChangeMask |
+ ColormapChangeMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ SubstructureNotifyMask);
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+}
+
+
+
+
+
+
+EAPI int
+ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret)
+{
+ XWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att)) return 0;
+ memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
+ att_ret->root = att.root;
+ att_ret->x = att.x;
+ att_ret->y = att.y;
+ att_ret->w = att.width;
+ att_ret->h = att.height;
+ att_ret->border = att.border_width;
+ att_ret->depth = att.depth;
+ if (att.map_state != IsUnmapped) att_ret->visible = 1;
+ if (att.map_state == IsViewable) att_ret->viewable = 1;
+ if (att.override_redirect) att_ret->override = 1;
+ if (att.class == InputOnly) att_ret->input_only = 1;
+ if (att.save_under) att_ret->save_under = 1;
+ att_ret->event_mask.mine = att.your_event_mask;
+ att_ret->event_mask.all = att.all_event_masks;
+ att_ret->event_mask.no_propagate = att.do_not_propagate_mask;
+ att_ret->window_gravity = att.win_gravity;
+ att_ret->pixel_gravity = att.bit_gravity;
+ att_ret->colormap = att.colormap;
+ att_ret->visual = att.visual;
+ return 1;
+}
+
+EAPI void
+ecore_x_window_save_set_add(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XAddToSaveSet(_ecore_x_disp, win);
+}
+
+EAPI void
+ecore_x_window_save_set_del(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XRemoveFromSaveSet(_ecore_x_disp, win);
+}
+
+EAPI Ecore_X_Window *
+ecore_x_window_children_get(Ecore_X_Window win, int *num)
+{
+ Ecore_X_Window *windows = NULL;
+ Window root_ret = 0, parent_ret = 0, *children_ret = NULL;
+ unsigned int children_ret_num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret,
+ &children_ret_num))
+ {
+ return NULL;
+ }
+ if (children_ret)
+ {
+ windows = malloc(children_ret_num * sizeof(Ecore_X_Window));
+ if (windows)
+ {
+ unsigned int i;
+
+ for (i = 0; i < children_ret_num; i++)
+ windows[i] = children_ret[i];
+ *num = children_ret_num;
+ }
+ XFree(children_ret);
+ }
+ return windows;
+}
+
+EAPI int
+ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XChangePointerControl(_ecore_x_disp, 1, 1,
+ accel_num, accel_denom, threshold);
+}
+
+EAPI int
+ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XGetPointerControl(_ecore_x_disp,
+ accel_num, accel_denom, threshold);
+}
+
+EAPI int
+ecore_x_pointer_mapping_set(unsigned char *map, int nmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XSetPointerMapping(_ecore_x_disp, map, nmap);
+}
+
+EAPI int
+ecore_x_pointer_mapping_get(unsigned char *map, int nmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XGetPointerMapping(_ecore_x_disp, map, nmap);
+}
+
+EAPI int
+ecore_x_pointer_grab(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGrabPointer(_ecore_x_disp, win, False,
+ ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ None, None, CurrentTime) == GrabSuccess) return 1;
+ return 0;
+}
+
+EAPI int
+ecore_x_pointer_confine_grab(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGrabPointer(_ecore_x_disp, win, False,
+ ButtonPressMask | ButtonReleaseMask |
+ EnterWindowMask | LeaveWindowMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ win, None, CurrentTime) == GrabSuccess) return 1;
+ return 0;
+}
+
+EAPI void
+ecore_x_pointer_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XUngrabPointer(_ecore_x_disp, CurrentTime);
+}
+
+EAPI int
+ecore_x_pointer_warp(Ecore_X_Window win, int x, int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y);
+}
+
+EAPI int
+ecore_x_keyboard_grab(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGrabKeyboard(_ecore_x_disp, win, False,
+ GrabModeAsync, GrabModeAsync,
+ CurrentTime) == GrabSuccess) return 1;
+ return 0;
+}
+
+EAPI void
+ecore_x_keyboard_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XUngrabKeyboard(_ecore_x_disp, CurrentTime);
+}
+
+EAPI void
+ecore_x_grab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_grab_count++;
+ if (_ecore_x_grab_count == 1) XGrabServer(_ecore_x_disp);
+}
+
+EAPI void
+ecore_x_ungrab(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_grab_count--;
+ if (_ecore_x_grab_count < 0) _ecore_x_grab_count = 0;
+ if (_ecore_x_grab_count == 0) XUngrabServer(_ecore_x_disp);
+}
+
+int _ecore_window_grabs_num = 0;
+Window *_ecore_window_grabs = NULL;
+int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
+void *_ecore_window_grab_replay_data;
+
+EAPI void
+ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_window_grab_replay_func = func;
+ _ecore_window_grab_replay_data = data;
+}
+
+EAPI void
+ecore_x_window_button_grab(Ecore_X_Window win, int button,
+ Ecore_X_Event_Mask event_mask,
+ int mod, int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i, ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ b = button;
+ if (b == 0) b = AnyButton;
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ ev = event_mask;
+ for (i = 0; i < 8; i++)
+ XGrabButton(_ecore_x_disp, b, m | locks[i],
+ win, False, ev, GrabModeSync, GrabModeAsync, None, None);
+ _ecore_window_grabs_num++;
+ _ecore_window_grabs = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num * sizeof(Window));
+ _ecore_window_grabs[_ecore_window_grabs_num - 1] = win;
+}
+
+void
+_ecore_x_sync_magic_send(int val, Ecore_X_Window swin)
+{
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = _ecore_x_private_win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = 27777;
+ xev.xclient.data.l[0] = 0x7162534;
+ xev.xclient.data.l[1] = 0x10000000 + val;
+ xev.xclient.data.l[2] = swin;
+ XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev);
+}
+
+void
+_ecore_x_window_grab_remove(Ecore_X_Window win)
+{
+ int i, shuffle = 0;
+
+ if (_ecore_window_grabs_num > 0)
+ {
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if (shuffle) _ecore_window_grabs[i - 1] = _ecore_window_grabs[i];
+ if ((!shuffle) && (_ecore_window_grabs[i] == win))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_window_grabs_num--;
+ _ecore_window_grabs = realloc(_ecore_window_grabs,
+ _ecore_window_grabs_num * sizeof(Window));
+ }
+ }
+}
+
+EAPI void
+ecore_x_window_button_ungrab(Ecore_X_Window win, int button,
+ int mod, int any_mod)
+{
+ unsigned int b;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ b = button;
+ if (b == 0) b = AnyButton;
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ XUngrabButton(_ecore_x_disp, b, m | locks[i], win);
+ _ecore_x_sync_magic_send(1, win);
+}
+
+int _ecore_key_grabs_num = 0;
+Window *_ecore_key_grabs = NULL;
+
+EAPI void
+ecore_x_window_key_grab(Ecore_X_Window win, const char *key,
+ int mod, int any_mod)
+{
+ KeyCode keycode = 0;
+ KeySym keysym;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol) return;
+ keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
+ }
+ if (keycode == 0) return;
+
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ XGrabKey(_ecore_x_disp, keycode, m | locks[i],
+ win, False, GrabModeSync, GrabModeAsync);
+ _ecore_key_grabs_num++;
+ _ecore_key_grabs = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Window));
+ _ecore_key_grabs[_ecore_key_grabs_num - 1] = win;
+}
+
+void
+_ecore_x_key_grab_remove(Ecore_X_Window win)
+{
+ int i, shuffle = 0;
+
+ if (_ecore_key_grabs_num > 0)
+ {
+ for (i = 0; i < _ecore_key_grabs_num; i++)
+ {
+ if (shuffle) _ecore_key_grabs[i - 1] = _ecore_key_grabs[i];
+ if ((!shuffle) && (_ecore_key_grabs[i] == win))
+ shuffle = 1;
+ }
+ if (shuffle)
+ {
+ _ecore_key_grabs_num--;
+ _ecore_key_grabs = realloc(_ecore_key_grabs,
+ _ecore_key_grabs_num * sizeof(Window));
+ }
+ }
+}
+
+EAPI void
+ecore_x_window_key_ungrab(Ecore_X_Window win, const char *key,
+ int mod, int any_mod)
+{
+ KeyCode keycode = 0;
+ KeySym keysym;
+ unsigned int m;
+ unsigned int locks[8];
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol) return;
+ keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key));
+ }
+ if (keycode == 0) return;
+
+ m = _ecore_x_event_modifier(mod);
+ if (any_mod) m = AnyModifier;
+ locks[0] = 0;
+ locks[1] = ECORE_X_LOCK_CAPS;
+ locks[2] = ECORE_X_LOCK_NUM;
+ locks[3] = ECORE_X_LOCK_SCROLL;
+ locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
+ locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
+ locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
+ for (i = 0; i < 8; i++)
+ XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win);
+ _ecore_x_sync_magic_send(2, win);
+}
+
+/**
+ * Send client message with given type and format 32.
+ *
+ * @param win The window the message is sent to.
+ * @param type The client message type.
+ * @param d0 The client message data item 1
+ * @param d1 The client message data item 2
+ * @param d2 The client message data item 3
+ * @param d3 The client message data item 4
+ * @param d4 The client message data item 5
+ *
+ * @return !0 on success.
+ */
+EAPI int
+ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type,
+ Ecore_X_Event_Mask mask,
+ long d0, long d1, long d2, long d3, long d4)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.window = win;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = type;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = d0;
+ xev.xclient.data.l[1] = d1;
+ xev.xclient.data.l[2] = d2;
+ xev.xclient.data.l[3] = d3;
+ xev.xclient.data.l[4] = d4;
+
+ return XSendEvent(_ecore_x_disp, win, False, mask, &xev);
+}
+
+/**
+ * Send client message with given type and format 8.
+ *
+ * @param win The window the message is sent to.
+ * @param type The client message type.
+ * @param data Data to be sent.
+ * @param len Number of data bytes, max 20.
+ *
+ * @return !0 on success.
+ */
+EAPI int
+ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type,
+ const void *data, int len)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.window = win;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = type;
+ xev.xclient.format = 8;
+ if (len > 20) len = 20;
+ memcpy(xev.xclient.data.b, data, len);
+ memset(xev.xclient.data.b + len, 0, 20 - len);
+
+ return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+EAPI int
+ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xmotion.type = MotionNotify;
+ xev.xmotion.window = win;
+ xev.xmotion.root = att.root;
+ xev.xmotion.subwindow = win;
+ xev.xmotion.time = _ecore_x_event_last_time;
+ xev.xmotion.x = x;
+ xev.xmotion.y = y;
+ xev.xmotion.x_root = rx;
+ xev.xmotion.y_root = ry;
+ xev.xmotion.state = 0;
+ xev.xmotion.is_hint = 0;
+ xev.xmotion.same_screen = 1;
+ return XSendEvent(_ecore_x_disp, win, True, PointerMotionMask, &xev);
+}
+
+EAPI int
+ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xbutton.type = ButtonPress;
+ xev.xbutton.window = win;
+ xev.xbutton.root = att.root;
+ xev.xbutton.subwindow = win;
+ xev.xbutton.time = _ecore_x_event_last_time;
+ xev.xbutton.x = x;
+ xev.xbutton.y = y;
+ xev.xbutton.x_root = rx;
+ xev.xbutton.y_root = ry;
+ xev.xbutton.state = 1 << b;
+ xev.xbutton.button = b;
+ xev.xbutton.same_screen = 1;
+ return XSendEvent(_ecore_x_disp, win, True, ButtonPressMask, &xev);
+}
+
+EAPI int
+ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b)
+{
+ XEvent xev;
+ XWindowAttributes att;
+ Window tw;
+ int rx, ry;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetWindowAttributes(_ecore_x_disp, win, &att);
+ XTranslateCoordinates(_ecore_x_disp, win, att.root, x, y, &rx, &ry, &tw);
+ xev.xbutton.type = ButtonRelease;
+ xev.xbutton.window = win;
+ xev.xbutton.root = att.root;
+ xev.xbutton.subwindow = win;
+ xev.xbutton.time = _ecore_x_event_last_time;
+ xev.xbutton.x = x;
+ xev.xbutton.y = y;
+ xev.xbutton.x_root = rx;
+ xev.xbutton.y_root = ry;
+ xev.xbutton.state = 0;
+ xev.xbutton.button = b;
+ xev.xbutton.same_screen = 1;
+ return XSendEvent(_ecore_x_disp, win, True, ButtonReleaseMask, &xev);
+}
+
+EAPI void
+ecore_x_focus_reset(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime);
+}
+
+EAPI void
+ecore_x_events_allow_all(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime);
+}
+
+EAPI void
+ecore_x_pointer_last_xy_get(int *x, int *y)
+{
+ if (x) *x = _ecore_x_event_last_root_x;
+ if (y) *y = _ecore_x_event_last_root_y;
+}
+
+EAPI void
+ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y)
+{
+ Window rwin, cwin;
+ int rx, ry, wx, wy, ret;
+ unsigned int mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = XQueryPointer(_ecore_x_disp, win, &rwin, &cwin, &rx, &ry, &wx, &wy, &mask);
+ if (!ret) wx = wy = -1;
+ if (x) *x = wx;
+ if (y) *y = wy;
+}
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+static int
+_ecore_x_event_modifier(unsigned int state)
+{
+ int xmodifiers = 0;
+
+ if (state & ECORE_EVENT_MODIFIER_SHIFT) xmodifiers |= ECORE_X_MODIFIER_SHIFT;
+ if (state & ECORE_EVENT_MODIFIER_CTRL) xmodifiers |= ECORE_X_MODIFIER_CTRL;
+ if (state & ECORE_EVENT_MODIFIER_ALT) xmodifiers |= ECORE_X_MODIFIER_ALT;
+ if (state & ECORE_EVENT_MODIFIER_WIN) xmodifiers |= ECORE_X_MODIFIER_WIN;
+ if (state & ECORE_EVENT_LOCK_SCROLL) xmodifiers |= ECORE_X_LOCK_SCROLL;
+ if (state & ECORE_EVENT_LOCK_NUM) xmodifiers |= ECORE_X_LOCK_NUM;
+ if (state & ECORE_EVENT_LOCK_CAPS) xmodifiers |= ECORE_X_LOCK_CAPS;
+
+ return xmodifiers;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif defined __GNUC__
+# define alloca __builtin_alloca
+#elif defined _AIX
+# define alloca __alloca
+#elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+#else
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+#endif
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#include "ecore_x_atoms_decl.h"
+
+typedef struct
+{
+ const char *name;
+ Ecore_X_Atom *atom;
+} Atom_Item;
+
+void
+_ecore_x_atoms_init(void)
+{
+ const Atom_Item items[] =
+ {
+ { "ATOM", &ECORE_X_ATOM_ATOM },
+ { "CARDINAL", &ECORE_X_ATOM_CARDINAL },
+ { "COMPOUND_TEXT", &ECORE_X_ATOM_COMPOUND_TEXT },
+ { "FILE_NAME", &ECORE_X_ATOM_FILE_NAME },
+ { "STRING", &ECORE_X_ATOM_STRING },
+ { "TEXT", &ECORE_X_ATOM_TEXT },
+ { "UTF8_STRING", &ECORE_X_ATOM_UTF8_STRING },
+ { "WINDOW", &ECORE_X_ATOM_WINDOW },
+
+ { "JXSelectionWindowProperty", &ECORE_X_ATOM_SELECTION_PROP_XDND },
+ { "XdndSelection", &ECORE_X_ATOM_SELECTION_XDND },
+ { "XdndAware", &ECORE_X_ATOM_XDND_AWARE },
+ { "XdndEnter", &ECORE_X_ATOM_XDND_ENTER },
+ { "XdndTypeList", &ECORE_X_ATOM_XDND_TYPE_LIST },
+ { "XdndPosition", &ECORE_X_ATOM_XDND_POSITION },
+ { "XdndActionCopy", &ECORE_X_ATOM_XDND_ACTION_COPY },
+ { "XdndActionMove", &ECORE_X_ATOM_XDND_ACTION_MOVE },
+ { "XdndActionPrivate", &ECORE_X_ATOM_XDND_ACTION_PRIVATE },
+ { "XdndActionAsk", &ECORE_X_ATOM_XDND_ACTION_ASK },
+ { "XdndActionList", &ECORE_X_ATOM_XDND_ACTION_LIST },
+ { "XdndActionLink", &ECORE_X_ATOM_XDND_ACTION_LINK },
+ { "XdndActionDescription", &ECORE_X_ATOM_XDND_ACTION_DESCRIPTION },
+ { "XdndProxy", &ECORE_X_ATOM_XDND_PROXY },
+ { "XdndStatus", &ECORE_X_ATOM_XDND_STATUS },
+ { "XdndLeave", &ECORE_X_ATOM_XDND_LEAVE },
+ { "XdndDrop", &ECORE_X_ATOM_XDND_DROP },
+ { "XdndFinished", &ECORE_X_ATOM_XDND_FINISHED },
+
+ { "XdndActionCopy", &ECORE_X_DND_ACTION_COPY },
+ { "XdndActionMove", &ECORE_X_DND_ACTION_MOVE },
+ { "XdndActionLink", &ECORE_X_DND_ACTION_LINK },
+ { "XdndActionAsk", &ECORE_X_DND_ACTION_ASK },
+ { "XdndActionPrivate", &ECORE_X_DND_ACTION_PRIVATE },
+
+ { "_E_FRAME_SIZE", &ECORE_X_ATOM_E_FRAME_SIZE },
+
+ { "_WIN_LAYER", &ECORE_X_ATOM_WIN_LAYER },
+
+ { "WM_NAME", &ECORE_X_ATOM_WM_NAME },
+ { "WM_ICON_NAME", &ECORE_X_ATOM_WM_ICON_NAME },
+ { "WM_NORMAL_HINTS", &ECORE_X_ATOM_WM_NORMAL_HINTS },
+ { "WM_SIZE_HINTS", &ECORE_X_ATOM_WM_SIZE_HINTS },
+ { "WM_HINTS", &ECORE_X_ATOM_WM_HINTS },
+ { "WM_CLASS", &ECORE_X_ATOM_WM_CLASS },
+ { "WM_TRANSIENT_FOR", &ECORE_X_ATOM_WM_TRANSIENT_FOR },
+ { "WM_PROTOCOLS", &ECORE_X_ATOM_WM_PROTOCOLS },
+ { "WM_COLORMAP_WINDOWS", &ECORE_X_ATOM_WM_COLORMAP_WINDOWS },
+ { "WM_COMMAND", &ECORE_X_ATOM_WM_COMMAND },
+ { "WM_CLIENT_MACHINE", &ECORE_X_ATOM_WM_CLIENT_MACHINE },
+
+ { "WM_STATE", &ECORE_X_ATOM_WM_STATE },
+ { "WM_ICON_SIZE", &ECORE_X_ATOM_WM_ICON_SIZE },
+
+ { "WM_CHANGE_STATE", &ECORE_X_ATOM_WM_CHANGE_STATE },
+
+ { "WM_TAKE_FOCUS", &ECORE_X_ATOM_WM_TAKE_FOCUS },
+ { "WM_SAVE_YOURSELF", &ECORE_X_ATOM_WM_SAVE_YOURSELF },
+ { "WM_DELETE_WINDOW", &ECORE_X_ATOM_WM_DELETE_WINDOW },
+
+ { "WM_COLORMAP_NOTIFY", &ECORE_X_ATOM_WM_COLORMAP_NOTIFY },
+
+ { "SM_CLIENT_ID", &ECORE_X_ATOM_SM_CLIENT_ID },
+ { "WM_CLIENT_LEADER", &ECORE_X_ATOM_WM_CLIENT_LEADER },
+ { "WM_WINDOW_ROLE", &ECORE_X_ATOM_WM_WINDOW_ROLE },
+
+ { "_MOTIF_WM_HINTS", &ECORE_X_ATOM_MOTIF_WM_HINTS },
+
+ { "_NET_SUPPORTED", &ECORE_X_ATOM_NET_SUPPORTED },
+ { "_NET_CLIENT_LIST", &ECORE_X_ATOM_NET_CLIENT_LIST },
+ { "_NET_CLIENT_LIST_STACKING", &ECORE_X_ATOM_NET_CLIENT_LIST_STACKING },
+ { "_NET_NUMBER_OF_DESKTOPS", &ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS },
+ { "_NET_DESKTOP_GEOMETRY", &ECORE_X_ATOM_NET_DESKTOP_GEOMETRY },
+ { "_NET_DESKTOP_VIEWPORT", &ECORE_X_ATOM_NET_DESKTOP_VIEWPORT },
+ { "_NET_CURRENT_DESKTOP", &ECORE_X_ATOM_NET_CURRENT_DESKTOP },
+ { "_NET_DESKTOP_NAMES", &ECORE_X_ATOM_NET_DESKTOP_NAMES },
+ { "_NET_ACTIVE_WINDOW", &ECORE_X_ATOM_NET_ACTIVE_WINDOW },
+ { "_NET_WORKAREA", &ECORE_X_ATOM_NET_WORKAREA },
+ { "_NET_SUPPORTING_WM_CHECK", &ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK },
+ { "_NET_VIRTUAL_ROOTS", &ECORE_X_ATOM_NET_VIRTUAL_ROOTS },
+ { "_NET_DESKTOP_LAYOUT", &ECORE_X_ATOM_NET_DESKTOP_LAYOUT },
+ { "_NET_SHOWING_DESKTOP", &ECORE_X_ATOM_NET_SHOWING_DESKTOP },
+
+ { "_NET_CLOSE_WINDOW", &ECORE_X_ATOM_NET_CLOSE_WINDOW },
+ { "_NET_MOVERESIZE_WINDOW", &ECORE_X_ATOM_NET_MOVERESIZE_WINDOW },
+ { "_NET_WM_MOVERESIZE", &ECORE_X_ATOM_NET_WM_MOVERESIZE },
+ { "_NET_RESTACK_WINDOW", &ECORE_X_ATOM_NET_RESTACK_WINDOW },
+
+ { "_NET_REQUEST_FRAME_EXTENTS", &ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS },
+
+ { "_NET_WM_NAME", &ECORE_X_ATOM_NET_WM_NAME },
+ { "_NET_WM_VISIBLE_NAME", &ECORE_X_ATOM_NET_WM_VISIBLE_NAME },
+ { "_NET_WM_ICON_NAME", &ECORE_X_ATOM_NET_WM_ICON_NAME },
+ { "_NET_WM_VISIBLE_ICON_NAME", &ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME },
+ { "_NET_WM_DESKTOP", &ECORE_X_ATOM_NET_WM_DESKTOP },
+
+ { "_NET_WM_WINDOW_TYPE", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE },
+ { "_NET_WM_WINDOW_TYPE_DESKTOP", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP },
+ { "_NET_WM_WINDOW_TYPE_DOCK", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK },
+ { "_NET_WM_WINDOW_TYPE_TOOLBAR", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR },
+ { "_NET_WM_WINDOW_TYPE_MENU", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU },
+ { "_NET_WM_WINDOW_TYPE_UTILITY", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY },
+ { "_NET_WM_WINDOW_TYPE_SPLASH", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH },
+ { "_NET_WM_WINDOW_TYPE_DIALOG", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG },
+ { "_NET_WM_WINDOW_TYPE_NORMAL", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL },
+ { "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU },
+ { "_NET_WM_WINDOW_TYPE_POPUP_MENU", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU },
+ { "_NET_WM_WINDOW_TYPE_TOOLTIP", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP },
+ { "_NET_WM_WINDOW_TYPE_NOTIFICATION", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION },
+ { "_NET_WM_WINDOW_TYPE_COMBO", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO },
+ { "_NET_WM_WINDOW_TYPE_DND", &ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND },
+
+ { "_NET_WM_STATE", &ECORE_X_ATOM_NET_WM_STATE },
+ { "_NET_WM_STATE_MODAL", &ECORE_X_ATOM_NET_WM_STATE_MODAL },
+ { "_NET_WM_STATE_STICKY", &ECORE_X_ATOM_NET_WM_STATE_STICKY },
+ { "_NET_WM_STATE_MAXIMIZED_VERT", &ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT },
+ { "_NET_WM_STATE_MAXIMIZED_HORZ", &ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ },
+ { "_NET_WM_STATE_SHADED", &ECORE_X_ATOM_NET_WM_STATE_SHADED },
+ { "_NET_WM_STATE_SKIP_TASKBAR", &ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR },
+ { "_NET_WM_STATE_SKIP_PAGER", &ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER },
+ { "_NET_WM_STATE_HIDDEN", &ECORE_X_ATOM_NET_WM_STATE_HIDDEN },
+ { "_NET_WM_STATE_FULLSCREEN", &ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN },
+ { "_NET_WM_STATE_ABOVE", &ECORE_X_ATOM_NET_WM_STATE_ABOVE },
+ { "_NET_WM_STATE_BELOW", &ECORE_X_ATOM_NET_WM_STATE_BELOW },
+ { "_NET_WM_STATE_DEMANDS_ATTENTION", &ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION },
+
+ { "_NET_WM_ALLOWED_ACTIONS", &ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS },
+ { "_NET_WM_ACTION_MOVE", &ECORE_X_ATOM_NET_WM_ACTION_MOVE },
+ { "_NET_WM_ACTION_RESIZE", &ECORE_X_ATOM_NET_WM_ACTION_RESIZE },
+ { "_NET_WM_ACTION_MINIMIZE", &ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE },
+ { "_NET_WM_ACTION_SHADE", &ECORE_X_ATOM_NET_WM_ACTION_SHADE },
+ { "_NET_WM_ACTION_STICK", &ECORE_X_ATOM_NET_WM_ACTION_STICK },
+ { "_NET_WM_ACTION_MAXIMIZE_HORZ", &ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ },
+ { "_NET_WM_ACTION_MAXIMIZE_VERT", &ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT },
+ { "_NET_WM_ACTION_FULLSCREEN", &ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN },
+ { "_NET_WM_ACTION_CHANGE_DESKTOP", &ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP },
+ { "_NET_WM_ACTION_CLOSE", &ECORE_X_ATOM_NET_WM_ACTION_CLOSE },
+ { "_NET_WM_ACTION_ABOVE", &ECORE_X_ATOM_NET_WM_ACTION_ABOVE },
+ { "_NET_WM_ACTION_BELOW", &ECORE_X_ATOM_NET_WM_ACTION_BELOW },
+
+ { "_NET_WM_STRUT", &ECORE_X_ATOM_NET_WM_STRUT },
+ { "_NET_WM_STRUT_PARTIAL", &ECORE_X_ATOM_NET_WM_STRUT_PARTIAL },
+ { "_NET_WM_ICON_GEOMETRY", &ECORE_X_ATOM_NET_WM_ICON_GEOMETRY },
+ { "_NET_WM_ICON", &ECORE_X_ATOM_NET_WM_ICON },
+ { "_NET_WM_PID", &ECORE_X_ATOM_NET_WM_PID },
+ { "_NET_WM_HANDLED_ICONS", &ECORE_X_ATOM_NET_WM_HANDLED_ICONS },
+ { "_NET_WM_USER_TIME", &ECORE_X_ATOM_NET_WM_USER_TIME },
+ { "_NET_STARTUP_ID", &ECORE_X_ATOM_NET_STARTUP_ID },
+ { "_NET_FRAME_EXTENTS", &ECORE_X_ATOM_NET_FRAME_EXTENTS },
+
+ { "_NET_WM_PING", &ECORE_X_ATOM_NET_WM_PING },
+ { "_NET_WM_SYNC_REQUEST", &ECORE_X_ATOM_NET_WM_SYNC_REQUEST },
+ { "_NET_WM_SYNC_REQUEST_COUNTER", &ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER },
+
+ { "_NET_WM_WINDOW_OPACITY", &ECORE_X_ATOM_NET_WM_WINDOW_OPACITY },
+ { "_NET_WM_WINDOW_SHADOW", &ECORE_X_ATOM_NET_WM_WINDOW_SHADOW },
+ { "_NET_WM_WINDOW_SHADE", &ECORE_X_ATOM_NET_WM_WINDOW_SHADE },
+
+ { "TARGETS", &ECORE_X_ATOM_SELECTION_TARGETS },
+ { "CLIPBOARD", &ECORE_X_ATOM_SELECTION_CLIPBOARD },
+ { "PRIMARY", &ECORE_X_ATOM_SELECTION_PRIMARY },
+ { "SECONDARY", &ECORE_X_ATOM_SELECTION_SECONDARY },
+ { "_ECORE_SELECTION_PRIMARY", &ECORE_X_ATOM_SELECTION_PROP_PRIMARY },
+ { "_ECORE_SELECTION_SECONDARY", &ECORE_X_ATOM_SELECTION_PROP_SECONDARY },
+ { "_ECORE_SELECTION_CLIPBOARD", &ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD },
+
+ { "_E_VIRTUAL_KEYBOARD", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD },
+ { "_E_VIRTUAL_KEYBOARD_STATE", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE },
+ { "_E_VIRTUAL_KEYBOARD_ON", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON },
+ { "_E_VIRTUAL_KEYBOARD_OFF", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF },
+ { "_E_VIRTUAL_KEYBOARD_ALPHA", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA },
+ { "_E_VIRTUAL_KEYBOARD_NUMERIC", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC },
+ { "_E_VIRTUAL_KEYBOARD_PIN", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN },
+ { "_E_VIRTUAL_KEYBOARD_PHONE_NUMBER", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER },
+ { "_E_VIRTUAL_KEYBOARD_HEX", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX },
+ { "_E_VIRTUAL_KEYBOARD_TERMINAL", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL },
+ { "_E_VIRTUAL_KEYBOARD_PASSWORD", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD },
+ { "_E_VIRTUAL_KEYBOARD_IP", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP },
+ { "_E_VIRTUAL_KEYBOARD_HOST", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST },
+ { "_E_VIRTUAL_KEYBOARD_FILE", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE },
+ { "_E_VIRTUAL_KEYBOARD_URL", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL },
+ { "_E_VIRTUAL_KEYBOARD_KEYPAD", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD },
+ { "_E_VIRTUAL_KEYBOARD_J2ME", &ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME },
+
+ { "_E_ILLUME_ZONE", &ECORE_X_ATOM_E_ILLUME_ZONE },
+ { "_E_ILLUME_ZONE_LIST", &ECORE_X_ATOM_E_ILLUME_ZONE_LIST },
+ { "_E_ILLUME_CONFORMANT", &ECORE_X_ATOM_E_ILLUME_CONFORMANT },
+ { "_E_ILLUME_MODE", &ECORE_X_ATOM_E_ILLUME_MODE },
+ { "_E_ILLUME_MODE_SINGLE", &ECORE_X_ATOM_E_ILLUME_MODE_SINGLE },
+ { "_E_ILLUME_MODE_DUAL_TOP", &ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP },
+ { "_E_ILLUME_MODE_DUAL_LEFT", &ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT },
+ { "_E_ILLUME_FOCUS_BACK", &ECORE_X_ATOM_E_ILLUME_FOCUS_BACK },
+ { "_E_ILLUME_FOCUS_FORWARD", &ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD },
+ { "_E_ILLUME_FOCUS_HOME", &ECORE_X_ATOM_E_ILLUME_FOCUS_HOME },
+ { "_E_ILLUME_CLOSE", &ECORE_X_ATOM_E_ILLUME_CLOSE },
+ { "_E_ILLUME_HOME_NEW", &ECORE_X_ATOM_E_ILLUME_HOME_NEW },
+ { "_E_ILLUME_HOME_DEL", &ECORE_X_ATOM_E_ILLUME_HOME_DEL },
+ { "_E_ILLUME_DRAG", &ECORE_X_ATOM_E_ILLUME_DRAG },
+ { "_E_ILLUME_DRAG_LOCKED", &ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED },
+ { "_E_ILLUME_DRAG_START", &ECORE_X_ATOM_E_ILLUME_DRAG_START },
+ { "_E_ILLUME_DRAG_END", &ECORE_X_ATOM_E_ILLUME_DRAG_END },
+ { "_E_ILLUME_INDICATOR_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY },
+ { "_E_ILLUME_SOFTKEY_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY },
+ { "_E_ILLUME_KEYBOARD_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY },
+ { "_E_ILLUME_QUICKPANEL", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL },
+ { "_E_ILLUME_QUICKPANEL_STATE", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE },
+ { "_E_ILLUME_QUICKPANEL_STATE_TOGGLE", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE },
+ { "_E_ILLUME_QUICKPANEL_ON", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON },
+ { "_E_ILLUME_QUICKPANEL_OFF", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF },
+ { "_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR },
+ { "_E_ILLUME_QUICKPANEL_PRIORITY_MINOR", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR },
+ { "_E_ILLUME_QUICKPANEL_ZONE", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE },
+ { "_E_ILLUME_QUICKPANEL_POSITION_UPDATE", &ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE },
+
+ { "_E_COMP_SYNC_COUNTER", &ECORE_X_ATOM_E_COMP_SYNC_COUNTER },
+ { "_E_COMP_SYNC_DRAW_DONE", &ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE },
+ { "_E_COMP_SYNC_SUPPORTED", &ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED },
+ { "_E_COMP_SYNC_BEGIN", &ECORE_X_ATOM_E_COMP_SYNC_BEGIN },
+ { "_E_COMP_SYNC_END", &ECORE_X_ATOM_E_COMP_SYNC_END },
+ { "_E_COMP_SYNC_CANCEL", &ECORE_X_ATOM_E_COMP_SYNC_CANCEL },
+
+ { "_E_COMP_FLUSH", &ECORE_X_ATOM_E_COMP_FLUSH },
+ { "_E_COMP_DUMP", &ECORE_X_ATOM_E_COMP_DUMP }
+ };
+ Atom *atoms;
+ char **names;
+ int i, num;
+
+ num = sizeof(items) / sizeof(Atom_Item);
+ atoms = alloca(num * sizeof(Atom));
+ names = alloca(num * sizeof(char *));
+ for (i = 0; i < num; i++) names[i] = (char *)items[i].name;
+ XInternAtoms(_ecore_x_disp, names, num, False, atoms);
+ for (i = 0; i < num; i++) *(items[i].atom) = atoms[i];
+}
+
+/**
+ * Retrieves the atom value associated with the given name.
+ * @param name The given name.
+ * @return Associated atom value.
+ */
+EAPI Ecore_X_Atom
+ecore_x_atom_get(const char *name)
+{
+ if (!_ecore_x_disp) return 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XInternAtom(_ecore_x_disp, name, False);
+}
+
+EAPI void
+ecore_x_atoms_get(const char **names, int num, Ecore_X_Atom *atoms)
+{
+ Atom *atoms_int;
+ int i;
+
+ if (!_ecore_x_disp) return;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atoms_int = alloca(num * sizeof(Atom));
+ XInternAtoms(_ecore_x_disp, (char **)names, num, False, atoms_int);
+ for (i = 0; i < num; i++)
+ atoms[i] = atoms_int[i];
+}
+
+EAPI char *
+ecore_x_atom_name_get(Ecore_X_Atom atom)
+{
+ char *name;
+ char *xname;
+
+ if (!_ecore_x_disp) return NULL;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xname = XGetAtomName(_ecore_x_disp, atom);
+ if (!xname) return NULL;
+
+ name = strdup(xname);
+ XFree(xname);
+
+ return name;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static int _composite_available;
+
+void
+_ecore_x_composite_init(void)
+{
+ _composite_available = 0;
+
+#ifdef ECORE_XCOMPOSITE
+ int major, minor;
+
+ if (XCompositeQueryVersion(_ecore_x_disp, &major, &minor))
+ _composite_available = 1;
+#endif
+}
+
+EAPI int
+ecore_x_composite_query(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _composite_available;
+}
+
+EAPI void
+ecore_x_composite_redirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch(type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeRedirectWindow(_ecore_x_disp, win, update);
+#endif
+}
+
+EAPI void
+ecore_x_composite_redirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch(type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeRedirectSubwindows(_ecore_x_disp, win, update);
+#endif
+}
+
+EAPI void
+ecore_x_composite_unredirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch(type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeUnredirectWindow(_ecore_x_disp, win, update);
+#endif
+}
+
+EAPI void
+ecore_x_composite_unredirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type)
+{
+#ifdef ECORE_XCOMPOSITE
+ int update = CompositeRedirectAutomatic;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch(type)
+ {
+ case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC:
+ update = CompositeRedirectAutomatic;
+ break;
+ case ECORE_X_COMPOSITE_UPDATE_MANUAL:
+ update = CompositeRedirectManual;
+ break;
+ }
+ XCompositeUnredirectSubwindows(_ecore_x_disp, win, update);
+#endif
+}
+
+EAPI Ecore_X_Pixmap
+ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win)
+{
+ Ecore_X_Pixmap pixmap = None;
+
+#ifdef ECORE_XCOMPOSITE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ pixmap = XCompositeNameWindowPixmap(_ecore_x_disp, win);
+#endif
+
+ return pixmap;
+}
+
+EAPI Ecore_X_Window
+ecore_x_composite_render_window_enable(Ecore_X_Window root)
+{
+ Ecore_X_Window win = 0;
+#ifdef ECORE_XCOMPOSITE
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ win = XCompositeGetOverlayWindow(_ecore_x_disp, root);
+ rect.x = -1;
+ rect.y = -1;
+ rect.width = 1;
+ rect.height = 1;
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeInput, 0, 0, &rect, 1,
+ ShapeSet, Unsorted);
+#endif
+ return win;
+}
+
+EAPI void
+ecore_x_composite_render_window_disable(Ecore_X_Window root)
+{
+#ifdef ECORE_XCOMPOSITE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XCompositeReleaseOverlayWindow(_ecore_x_disp, root);
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "ecore_x_private.h"
+
+
+EAPI int
+ecore_x_cursor_color_supported_get(void)
+{
+ return _ecore_x_xcursor;
+}
+
+EAPI Ecore_X_Cursor
+ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y)
+{
+#ifdef ECORE_XCURSOR
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (_ecore_x_xcursor)
+ {
+ Cursor c;
+ XcursorImage *xci;
+
+ xci = XcursorImageCreate(w, h);
+ if (xci)
+ {
+ int i;
+
+ xci->xhot = hot_x;
+ xci->yhot = hot_y;
+ xci->delay = 0;
+ for (i = 0; i < (w * h); i++)
+ {
+// int r, g, b, a;
+//
+// a = (pixels[i] >> 24) & 0xff;
+// r = (((pixels[i] >> 16) & 0xff) * a) / 0xff;
+// g = (((pixels[i] >> 8 ) & 0xff) * a) / 0xff;
+// b = (((pixels[i] ) & 0xff) * a) / 0xff;
+ xci->pixels[i] = pixels[i];
+// (a << 24) | (r << 16) | (g << 8) | (b);
+ }
+ c = XcursorImageLoadCursor(_ecore_x_disp, xci);
+ XcursorImageDestroy(xci);
+ return c;
+ }
+ }
+ else
+#endif
+ {
+ XColor c1, c2;
+ Cursor c;
+ Pixmap pmap, mask;
+ GC gc;
+ XGCValues gcv;
+ XImage *xim;
+ unsigned int *pix;
+ int fr, fg, fb, br, bg, bb;
+ int brightest = 0;
+ int darkest = 255 * 3;
+ int x, y;
+ const int dither[2][2] =
+ {
+ {0, 2},
+ {3, 1}
+ };
+
+ pmap = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
+ mask = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
+ xim = XCreateImage(_ecore_x_disp,
+ DefaultVisual(_ecore_x_disp, 0),
+ 1, ZPixmap, 0, NULL, w, h, 32, 0);
+ xim->data = malloc(xim->bytes_per_line * xim->height);
+
+ fr = 0x00; fg = 0x00; fb = 0x00;
+ br = 0xff; bg = 0xff; bb = 0xff;
+ pix = (unsigned int*)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int r, g, b, a;
+
+ a = (pix[0] >> 24) & 0xff;
+ r = (pix[0] >> 16) & 0xff;
+ g = (pix[0] >> 8 ) & 0xff;
+ b = (pix[0] ) & 0xff;
+ if (a > 0)
+ {
+ if ((r + g + b) > brightest)
+ {
+ brightest = r + g + b;
+ br = r;
+ bg = g;
+ bb = b;
+ }
+ if ((r + g + b) < darkest)
+ {
+ darkest = r + g + b;
+ fr = r;
+ fg = g;
+ fb = b;
+ }
+ }
+ pix++;
+ }
+ }
+
+ pix = (unsigned int*)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int v;
+ int r, g, b;
+ int d1, d2;
+
+ r = (pix[0] >> 16) & 0xff;
+ g = (pix[0] >> 8 ) & 0xff;
+ b = (pix[0] ) & 0xff;
+ d1 =
+ ((r - fr) * (r - fr)) +
+ ((g - fg) * (g - fg)) +
+ ((b - fb) * (b - fb));
+ d2 =
+ ((r - br) * (r - br)) +
+ ((g - bg) * (g - bg)) +
+ ((b - bb) * (b - bb));
+ if (d1 + d2)
+ {
+ v = (((d2 * 255) / (d1 + d2)) * 5) / 256;
+ if (v > dither[x & 0x1][y & 0x1]) v = 1;
+ else v = 0;
+ }
+ else
+ {
+ v = 0;
+ }
+ XPutPixel(xim, x, y, v);
+ pix++;
+ }
+ }
+ gc = XCreateGC(_ecore_x_disp, pmap, 0, &gcv);
+ XPutImage(_ecore_x_disp, pmap, gc, xim, 0, 0, 0, 0, w, h);
+ XFreeGC(_ecore_x_disp, gc);
+
+ pix = (unsigned int*)pixels;
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ {
+ int v;
+
+ v = (((pix[0] >> 24) & 0xff) * 5) / 256;
+ if (v > dither[x & 0x1][y & 0x1]) v = 1;
+ else v = 0;
+ XPutPixel(xim, x, y, v);
+ pix++;
+ }
+ }
+ gc = XCreateGC(_ecore_x_disp, mask, 0, &gcv);
+ XPutImage(_ecore_x_disp, mask, gc, xim, 0, 0, 0, 0, w, h);
+ XFreeGC(_ecore_x_disp, gc);
+
+ free(xim->data);
+ xim->data = NULL;
+ XDestroyImage(xim);
+
+ c1.pixel = 0;
+ c1.red = fr << 8 | fr;
+ c1.green = fg << 8 | fg;
+ c1.blue = fb << 8 | fb;
+ c1.flags = DoRed | DoGreen | DoBlue;
+
+ c2.pixel = 0;
+ c2.red = br << 8 | br;
+ c2.green = bg << 8 | bg;
+ c2.blue = bb << 8 | bb;
+ c2.flags = DoRed | DoGreen | DoBlue;
+
+ c = XCreatePixmapCursor(_ecore_x_disp,
+ pmap, mask,
+ &c1, &c2,
+ hot_x, hot_y);
+ XFreePixmap(_ecore_x_disp, pmap);
+ XFreePixmap(_ecore_x_disp, mask);
+ return c;
+ }
+ return 0;
+}
+
+EAPI void
+ecore_x_cursor_free(Ecore_X_Cursor c)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFreeCursor(_ecore_x_disp, c);
+}
+
+/*
+ * Returns the cursor for the given shape.
+ * Note that the return value must not be freed with
+ * ecore_x_cursor_free()!
+ */
+EAPI Ecore_X_Cursor
+ecore_x_cursor_shape_get(int shape)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* Shapes are defined in Ecore_X_Cursor.h */
+ return XCreateFontCursor(_ecore_x_disp, shape);
+}
+
+EAPI void
+ecore_x_cursor_size_set(int size)
+{
+#ifdef ECORE_XCURSOR
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XcursorSetDefaultSize(_ecore_x_disp, size);
+#else
+ size = 0;
+#endif
+}
+
+EAPI int
+ecore_x_cursor_size_get(void)
+{
+#ifdef ECORE_XCURSOR
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XcursorGetDefaultSize(_ecore_x_disp);
+#else
+ return 0;
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static int _damage_available;
+#ifdef ECORE_XDAMAGE
+static int _damage_major, _damage_minor;
+#endif
+
+void
+_ecore_x_damage_init(void)
+{
+#ifdef ECORE_XDAMAGE
+ _damage_major = 1;
+ _damage_minor = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XDamageQueryVersion(_ecore_x_disp, &_damage_major, &_damage_minor))
+ _damage_available = 1;
+ else
+ _damage_available = 0;
+#else
+ _damage_available = 0;
+#endif
+}
+
+EAPI int
+ecore_x_damage_query(void)
+{
+ return _damage_available;
+}
+
+EAPI Ecore_X_Damage
+ecore_x_damage_new(Ecore_X_Drawable d, Ecore_X_Damage_Report_Level level)
+{
+#ifdef ECORE_XDAMAGE
+ Ecore_X_Damage damage;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ damage = XDamageCreate(_ecore_x_disp, d, level);
+ return damage;
+#else
+ return 0;
+#endif
+}
+
+EAPI void
+ecore_x_damage_free(Ecore_X_Damage damage)
+{
+#ifdef ECORE_XDAMAGE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDamageDestroy(_ecore_x_disp, damage);
+#endif
+}
+
+EAPI void
+ecore_x_damage_subtract(Ecore_X_Damage damage, Ecore_X_Region repair, Ecore_X_Region parts)
+{
+#ifdef ECORE_XDAMAGE
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDamageSubtract(_ecore_x_disp, damage, repair, parts);
+#endif
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+EAPI int ECORE_X_EVENT_XDND_ENTER = 0;
+EAPI int ECORE_X_EVENT_XDND_POSITION = 0;
+EAPI int ECORE_X_EVENT_XDND_STATUS = 0;
+EAPI int ECORE_X_EVENT_XDND_LEAVE = 0;
+EAPI int ECORE_X_EVENT_XDND_DROP = 0;
+EAPI int ECORE_X_EVENT_XDND_FINISHED = 0;
+
+static Ecore_X_DND_Source *_source = NULL;
+static Ecore_X_DND_Target *_target = NULL;
+static int _ecore_x_dnd_init_count = 0;
+
+typedef struct _Version_Cache_Item
+{
+ Ecore_X_Window win;
+ int ver;
+} Version_Cache_Item;
+static Version_Cache_Item *_version_cache = NULL;
+static int _version_cache_num = 0, _version_cache_alloc = 0;
+
+void
+_ecore_x_dnd_init(void)
+{
+ if (!_ecore_x_dnd_init_count)
+ {
+ _source = calloc(1, sizeof(Ecore_X_DND_Source));
+ _source->version = ECORE_X_DND_VERSION;
+ _source->win = None;
+ _source->dest = None;
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ _source->prev.window = 0;
+
+ _target = calloc(1, sizeof(Ecore_X_DND_Target));
+ _target->win = None;
+ _target->source = None;
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+
+ ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_DROP = ecore_event_type_new();
+ ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new();
+ }
+
+ _ecore_x_dnd_init_count++;
+}
+
+void
+_ecore_x_dnd_shutdown(void)
+{
+ _ecore_x_dnd_init_count--;
+ if (_ecore_x_dnd_init_count > 0)
+ return;
+
+ if (_source)
+ free(_source);
+ _source = NULL;
+
+ if (_target)
+ free(_target);
+ _target = NULL;
+
+ _ecore_x_dnd_init_count = 0;
+}
+
+static int
+_ecore_x_dnd_converter_copy(char *target __UNUSED__, void *data, int size, void **data_ret, int *size_ret)
+{
+ XTextProperty text_prop;
+ char *mystr;
+ XICCEncodingStyle style = XTextStyle;
+
+ if (!data || !size)
+ return 0;
+
+ mystr = calloc(1, size + 1);
+ if (!mystr) return 0;
+ memcpy(mystr, data, size);
+
+ if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success)
+ {
+ int bufsize = strlen((char *)text_prop.value) + 1;
+ *data_ret = malloc(bufsize);
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ free(mystr);
+ return 1;
+ }
+ else
+ {
+ free(mystr);
+ return 0;
+ }
+}
+
+EAPI void
+ecore_x_dnd_aware_set(Ecore_X_Window win, int on)
+{
+ Ecore_X_Atom prop_data = ECORE_X_DND_VERSION;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (on)
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_AWARE,
+ XA_ATOM, 32, &prop_data, 1);
+ else
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE);
+}
+
+EAPI int
+ecore_x_dnd_version_get(Ecore_X_Window win)
+{
+ unsigned char *prop_data;
+ int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ // this looks hacky - and it is, but we need a way of caching info about
+ // a window while dragging, because we literally query this every mouse
+ // move and going to and from x multiple times per move is EXPENSIVE
+ // and slows things down, puts lots of load on x etc.
+ if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+ {
+ if (_version_cache)
+ {
+ int i;
+
+ for (i = 0; i < _version_cache_num; i++)
+ {
+ if (_version_cache[i].win == win)
+ return _version_cache[i].ver;
+ }
+ }
+ }
+
+ if (ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_AWARE,
+ XA_ATOM, 32, &prop_data, &num))
+ {
+ int version = (int) *prop_data;
+ free(prop_data);
+ if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+ {
+ _version_cache_num++;
+ if (_version_cache_num > _version_cache_alloc)
+ _version_cache_alloc += 16;
+ _version_cache = realloc(_version_cache, _version_cache_alloc * sizeof(Version_Cache_Item));
+ _version_cache[_version_cache_num - 1].win = win;
+ _version_cache[_version_cache_num - 1].ver = version;
+ }
+ return version;
+ }
+ if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
+ {
+ _version_cache_num++;
+ if (_version_cache_num > _version_cache_alloc)
+ _version_cache_alloc += 16;
+ _version_cache = realloc(_version_cache, _version_cache_alloc * sizeof(Version_Cache_Item));
+ _version_cache[_version_cache_num - 1].win = win;
+ _version_cache[_version_cache_num - 1].ver = 0;
+ }
+ return 0;
+}
+
+EAPI int
+ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type)
+{
+ int num, i, ret = 0;
+ unsigned char *data;
+ Ecore_X_Atom *atoms, atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, &data, &num))
+ return ret;
+
+ atom = ecore_x_atom_get(type);
+ atoms = (Ecore_X_Atom *)data;
+
+ for (i = 0; i < num; ++i)
+ {
+ if (atom == atoms[i])
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ XFree(data);
+ return ret;
+}
+
+EAPI void
+ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_Atom *oldset = NULL, *newset = NULL;
+ int i, j = 0, num = 0;
+ unsigned char *data = NULL;
+ unsigned char *old_data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = ecore_x_atom_get(type);
+ ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, &old_data, &num);
+ oldset = (Ecore_X_Atom *)old_data;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (on)
+ {
+ if (ecore_x_dnd_type_isset(win, type))
+ {
+ XFree(old_data);
+ return;
+ }
+ newset = calloc(num + 1, sizeof(Ecore_X_Atom));
+ if (!newset) return;
+ data = (unsigned char *)newset;
+
+ for (i = 0; i < num; i++)
+ newset[i + 1] = oldset[i];
+ /* prepend the new type */
+ newset[0] = atom;
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num + 1);
+ }
+ else
+ {
+ if (!ecore_x_dnd_type_isset(win, type))
+ {
+ XFree(old_data);
+ return;
+ }
+ newset = calloc(num - 1, sizeof(Ecore_X_Atom));
+ if (!newset)
+ {
+ XFree(old_data);
+ return;
+ }
+ data = (unsigned char *)newset;
+ for (i = 0; i < num; i++)
+ if (oldset[i] != atom)
+ newset[j++] = oldset[i];
+
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num - 1);
+ }
+ XFree(oldset);
+ free(newset);
+}
+
+EAPI void
+ecore_x_dnd_types_set(Ecore_X_Window win, const char **types, unsigned int num_types)
+{
+ Ecore_X_Atom *newset = NULL;
+ unsigned int i;
+ unsigned char *data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!num_types)
+ {
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_TYPE_LIST);
+ }
+ else
+ {
+ newset = calloc(num_types, sizeof(Ecore_X_Atom));
+ if (!newset) return;
+ data = (unsigned char *)newset;
+ for (i = 0; i < num_types; i++)
+ {
+ newset[i] = ecore_x_atom_get(types[i]);
+ ecore_x_selection_converter_atom_add(newset[i], _ecore_x_dnd_converter_copy);
+ }
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, data, num_types);
+ free(newset);
+ }
+}
+
+EAPI void
+ecore_x_dnd_actions_set(Ecore_X_Window win, Ecore_X_Atom *actions, unsigned int num_actions)
+{
+ unsigned int i;
+ unsigned char *data = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!num_actions)
+ {
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_ACTION_LIST);
+ }
+ else
+ {
+ data = (unsigned char *)actions;
+ for (i = 0; i < num_actions; i++)
+ {
+ ecore_x_selection_converter_atom_add(actions[i], _ecore_x_dnd_converter_copy);
+ }
+ ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_ACTION_LIST,
+ XA_ATOM, 32, data, num_actions);
+ }
+}
+
+Ecore_X_DND_Source *
+_ecore_x_dnd_source_get(void)
+{
+ return _source;
+}
+
+Ecore_X_DND_Target *
+_ecore_x_dnd_target_get(void)
+{
+ return _target;
+}
+
+EAPI int
+ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size)
+{
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_dnd_version_get(source))
+ return 0;
+
+ /* Take ownership of XdndSelection */
+ if (!ecore_x_selection_xdnd_set(source, data, size))
+ return 0;
+
+ if (_version_cache)
+ {
+ free(_version_cache);
+ _version_cache = NULL;
+ _version_cache_num = 0;
+ _version_cache_alloc = 0;
+ }
+ ecore_x_window_shadow_tree_flush();
+
+ _source->win = source;
+ ecore_x_window_ignore_set(_source->win, 1);
+ _source->state = ECORE_X_DND_SOURCE_DRAGGING;
+ _source->time = _ecore_x_event_last_time;
+ _source->prev.window = 0;
+
+ /* Default Accepted Action: move */
+ _source->action = ECORE_X_ATOM_XDND_ACTION_MOVE;
+ _source->accepted_action = None;
+ _source->dest = None;
+
+ return 1;
+}
+
+EAPI int
+ecore_x_dnd_drop(void)
+{
+ XEvent xev;
+ int status = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (_source->dest)
+ {
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.format = 32;
+ xev.xclient.window = _source->dest;
+
+ if (_source->will_accept)
+ {
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = _source->time;
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->state = ECORE_X_DND_SOURCE_DROPPED;
+ status = 1;
+ }
+ else
+ {
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ }
+ else
+ {
+ /* Dropping on nothing */
+ ecore_x_selection_xdnd_clear();
+ _source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ ecore_x_window_ignore_set(_source->win, 0);
+
+ _source->prev.window = 0;
+
+ return status;
+}
+
+EAPI void
+ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action)
+{
+ XEvent xev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ memset(&xev, 0, sizeof(XEvent));
+
+ _target->will_accept = will_accept;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_STATUS;
+ xev.xclient.format = 32;
+ xev.xclient.window = _target->source;
+
+ xev.xclient.data.l[0] = _target->win;
+ xev.xclient.data.l[1] = 0;
+ if (will_accept)
+ xev.xclient.data.l[1] |= 0x1UL;
+ if (!suppress)
+ xev.xclient.data.l[1] |= 0x2UL;
+
+ /* Set rectangle information */
+ xev.xclient.data.l[2] = rectangle.x;
+ xev.xclient.data.l[2] <<= 16;
+ xev.xclient.data.l[2] |= rectangle.y;
+ xev.xclient.data.l[3] = rectangle.width;
+ xev.xclient.data.l[3] <<= 16;
+ xev.xclient.data.l[3] |= rectangle.height;
+
+ if (will_accept)
+ {
+ xev.xclient.data.l[4] = action;
+ _target->accepted_action = action;
+ }
+ else
+ {
+ xev.xclient.data.l[4] = None;
+ _target->accepted_action = action;
+ }
+
+ XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev);
+}
+
+EAPI void
+ecore_x_dnd_send_finished(void)
+{
+ XEvent xev;
+
+ if (_target->state == ECORE_X_DND_TARGET_IDLE)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_FINISHED;
+ xev.xclient.format = 32;
+ xev.xclient.window = _target->source;
+
+ xev.xclient.data.l[0] = _target->win;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+ if (_target->will_accept)
+ {
+ xev.xclient.data.l[1] |= 0x1UL;
+ xev.xclient.data.l[2] = _target->accepted_action;
+ }
+ XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev);
+
+ _target->state = ECORE_X_DND_TARGET_IDLE;
+}
+
+void
+ecore_x_dnd_source_action_set(Ecore_X_Atom action)
+{
+ _source->action = action;
+ if (_source->prev.window)
+ _ecore_x_dnd_drag(_source->prev.window, _source->prev.x, _source->prev.y);
+}
+
+Ecore_X_Atom
+ecore_x_dnd_source_action_get(void)
+{
+ return _source->action;
+}
+
+void
+_ecore_x_dnd_drag(Ecore_X_Window root, int x, int y)
+{
+ XEvent xev;
+ Ecore_X_Window win;
+ Ecore_X_Window *skip;
+ int num;
+
+ if (_source->state != ECORE_X_DND_SOURCE_DRAGGING)
+ return;
+
+ /* Preinitialize XEvent struct */
+ memset(&xev, 0, sizeof(XEvent));
+ xev.xany.type = ClientMessage;
+ xev.xany.display = _ecore_x_disp;
+ xev.xclient.format = 32;
+
+ /* Attempt to find a DND-capable window under the cursor */
+ skip = ecore_x_window_ignore_list(&num);
+// WARNING - this function is HEAVY. it goes to and from x a LOT walking the
+// window tree - use the SHADOW version - makes a 1-off tree copy, then uses
+// that instead.
+// win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
+ win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num);
+
+// NOTE: This now uses the shadow version to find parent windows
+// while ((win) && !(ecore_x_dnd_version_get(win)))
+// win = ecore_x_window_parent_get(win);
+ while ((win) && !(ecore_x_dnd_version_get(win)))
+ win = ecore_x_window_shadow_parent_get(root, win);
+
+ /* Send XdndLeave to current destination window if we have left it */
+ if ((_source->dest) && (win != _source->dest))
+ {
+ xev.xclient.window = _source->dest;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+
+ XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
+ _source->suppress = 0;
+ }
+
+ if (win)
+ {
+ int x1, x2, y1, y2;
+
+ _source->version = MIN(ECORE_X_DND_VERSION,
+ ecore_x_dnd_version_get(win));
+ if (win != _source->dest)
+ {
+ int i;
+ unsigned char *data;
+ Ecore_X_Atom *types;
+
+ ecore_x_window_prop_property_get(_source->win, ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM, 32, &data, &num);
+ types = (Ecore_X_Atom *)data;
+
+ /* Entered new window, send XdndEnter */
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0;
+ if (num > 3)
+ xev.xclient.data.l[1] |= 0x1UL;
+ else
+ xev.xclient.data.l[1] &= 0xfffffffeUL;
+ xev.xclient.data.l[1] |= ((unsigned long) _source->version) << 24;
+
+ for (i = 2; i < 5; i++)
+ xev.xclient.data.l[i] = 0;
+ for (i = 0; i < MIN(num, 3); ++i)
+ xev.xclient.data.l[i + 2] = types[i];
+ XFree(data);
+ XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+ _source->await_status = 0;
+ _source->will_accept = 0;
+ }
+
+ /* Determine if we're still in the rectangle from the last status */
+ x1 = _source->rectangle.x;
+ x2 = _source->rectangle.x + _source->rectangle.width;
+ y1 = _source->rectangle.y;
+ y2 = _source->rectangle.y + _source->rectangle.height;
+
+ if ((!_source->await_status) ||
+ (!_source->suppress) ||
+ ((x < x1) || (x > x2) || (y < y1) || (y > y2)))
+ {
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_XDND_POSITION;
+ xev.xclient.data.l[0] = _source->win;
+ xev.xclient.data.l[1] = 0; /* Reserved */
+ xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
+ xev.xclient.data.l[3] = _source->time; /* Version 1 */
+ xev.xclient.data.l[4] = _source->action; /* Version 2, Needs to be pre-set */
+ XSendEvent(_ecore_x_disp, win, False, 0, &xev);
+
+ _source->await_status = 1;
+ }
+ }
+
+ _source->prev.x = x;
+ _source->prev.y = y;
+ _source->prev.window = root;
+ _source->dest = win;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+
+static int _dpms_available;
+
+void
+_ecore_x_dpms_init(void)
+{
+#ifdef ECORE_XDPMS
+ int _dpms_major, _dpms_minor;
+
+ _dpms_major = 1;
+ _dpms_minor = 0;
+
+ if (DPMSGetVersion(_ecore_x_disp, &_dpms_major, &_dpms_minor))
+ _dpms_available = 1;
+ else
+ _dpms_available = 0;
+#else
+ _dpms_available = 0;
+#endif
+}
+
+/**
+ * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions
+ *
+ * Functions related to the X DPMS extension.
+ */
+
+/**
+ * Checks if the X DPMS extension is available on the server.
+ * @return @c 1 if the X DPMS extension is available, @c 0 otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_query(void)
+{
+ return _dpms_available;
+}
+
+/**
+ * Checks if the X server is capable of DPMS.
+ * @return @c 1 if the X server is capable of DPMS, @c 0 otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_capable_get(void)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return DPMSCapable(_ecore_x_disp);
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Checks the DPMS state of the display.
+ * @return @c 1 if DPMS is enabled, @c 0 otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_enabled_get(void)
+{
+#ifdef ECORE_XDPMS
+ unsigned char state;
+ unsigned short power_lvl;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSInfo(_ecore_x_disp, &power_lvl, &state);
+ return state;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Sets the DPMS state of the display.
+ * @param enabled @c 0 to disable DPMS characteristics of the server, enable it otherwise.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_enabled_set(int enabled)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (enabled)
+ DPMSEnable(_ecore_x_disp);
+ else
+ DPMSDisable(_ecore_x_disp);
+#endif
+}
+
+/**
+ * Gets the timeouts. The values are in unit of seconds.
+ * @param standby Amount of time of inactivity before standby mode will be invoked.
+ * @param suspend Amount of time of inactivity before the screen is placed into suspend mode.
+ * @param off Amount of time of inactivity before the monitor is shut off.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeouts_get(unsigned int *standby, unsigned int *suspend, unsigned int *off)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, (unsigned short *)standby,
+ (unsigned short *)suspend, (unsigned short *)off);
+#endif
+}
+
+/**
+ * Sets the timeouts. The values are in unit of seconds.
+ * @param standby Amount of time of inactivity before standby mode will be invoked.
+ * @param suspend Amount of time of inactivity before the screen is placed into suspend mode.
+ * @param off Amount of time of inactivity before the monitor is shut off.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI int
+ecore_x_dpms_timeouts_set(unsigned int standby, unsigned int suspend, unsigned int off)
+{
+#ifdef ECORE_XDPMS
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return DPMSSetTimeouts(_ecore_x_disp, standby, suspend, off);
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Returns the amount of time of inactivity before standby mode is invoked.
+ * @return The standby timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_standby_get()
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ return standby;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Returns the amount of time of inactivity before the second level of
+ * power saving is invoked.
+ * @return The suspend timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_suspend_get()
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ return suspend;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Returns the amount of time of inactivity before the third and final
+ * level of power saving is invoked.
+ * @return The off timeout value.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI unsigned int
+ecore_x_dpms_timeout_off_get()
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ return off;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Sets the standby timeout (in unit of seconds).
+ * @param new_standby Amount of time of inactivity before standby mode will be invoked.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_standby_set(unsigned int new_timeout)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ DPMSSetTimeouts(_ecore_x_disp, new_timeout, suspend, off);
+#endif
+}
+
+/**
+ * Sets the suspend timeout (in unit of seconds).
+ * @param suspend Amount of time of inactivity before the screen is placed into suspend mode.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_suspend_set(unsigned int new_timeout)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ DPMSSetTimeouts(_ecore_x_disp, standby, new_timeout, off);
+#endif
+}
+
+/**
+ * Sets the off timeout (in unit of seconds).
+ * @param off Amount of time of inactivity before the monitor is shut off.
+ * @ingroup Ecore_X_DPMS_Group
+ */
+EAPI void
+ecore_x_dpms_timeout_off_set(unsigned int new_timeout)
+{
+#ifdef ECORE_XDPMS
+ unsigned short standby, suspend, off;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off);
+ DPMSSetTimeouts(_ecore_x_disp, standby, suspend, new_timeout);
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+
+
+/**
+ * @defgroup Ecore_X_Drawable_Group X Drawable Functions
+ *
+ * Functions that operate on drawables.
+ */
+
+
+/**
+ * Retrieves the geometry of the given drawable.
+ * @param d The given drawable.
+ * @param x Pointer to an integer into which the X position is to be stored.
+ * @param y Pointer to an integer into which the Y position is to be stored.
+ * @param w Pointer to an integer into which the width is to be stored.
+ * @param h Pointer to an integer into which the height is to be stored.
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI void
+ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h)
+{
+ Window dummy_win;
+ int ret_x, ret_y;
+ unsigned int ret_w, ret_h, dummy_border, dummy_depth;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &ret_x, &ret_y,
+ &ret_w, &ret_h, &dummy_border, &dummy_depth))
+ {
+ ret_x = 0;
+ ret_y = 0;
+ ret_w = 0;
+ ret_h = 0;
+ }
+
+ if (x) *x = ret_x;
+ if (y) *y = ret_y;
+ if (w) *w = (int) ret_w;
+ if (h) *h = (int) ret_h;
+}
+
+/**
+ * Retrieves the width of the border of the given drawable.
+ * @param d The given drawable.
+ * @return The border width of the given drawable.
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI int
+ecore_x_drawable_border_width_get(Ecore_X_Drawable d)
+{
+ Window dummy_win;
+ int dummy_x, dummy_y;
+ unsigned int dummy_w, dummy_h, border_ret, dummy_depth;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y,
+ &dummy_w, &dummy_h, &border_ret, &dummy_depth))
+ border_ret = 0;
+
+ return (int) border_ret;
+}
+
+/**
+ * Retrieves the depth of the given drawable.
+ * @param d The given drawable.
+ * @return The depth of the given drawable.
+ * @ingroup Ecore_X_Drawable_Group
+ */
+EAPI int
+ecore_x_drawable_depth_get(Ecore_X_Drawable d)
+{
+ Window dummy_win;
+ int dummy_x, dummy_y;
+ unsigned int dummy_w, dummy_h, dummy_border, depth_ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y,
+ &dummy_w, &dummy_h, &dummy_border, &depth_ret))
+ depth_ret = 0;
+
+ return (int) depth_ret;
+}
+
+/**
+ * Fill the specified rectangle on a drawable.
+ * @param d The given drawable.
+ * @param gc The graphic context that controls the fill rules.
+ * @param x The X coordinate of the top-left corner of the rectangle.
+ * @param y The Y coordinate of the top-left corner of the rectangle.
+ * @param width The width of the rectangle.
+ * @param height The height of the rectangle.
+ */
+EAPI void
+ecore_x_drawable_rectangle_fill(Ecore_X_Drawable d, Ecore_X_GC gc, int x, int y, int width, int height)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFillRectangle(_ecore_x_disp, d, gc, x, y, width, height);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * OLD E hints
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+EAPI void
+ecore_x_e_init(void)
+{
+}
+
+EAPI void
+ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb)
+{
+ unsigned int frames[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ frames[0] = fl;
+ frames[1] = fr;
+ frames[2] = ft;
+ frames[3] = fb;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_FRAME_SIZE, frames, 4);
+}
+
+EAPI void
+ecore_x_e_virtual_keyboard_set(Ecore_X_Window win, unsigned int is_keyboard)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD,
+ &is_keyboard, 1);
+}
+
+EAPI int
+ecore_x_e_virtual_keyboard_get(Ecore_X_Window win)
+{
+ unsigned int val;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD, &val, 1))
+ return 0;
+ return val;
+}
+
+static Ecore_X_Virtual_Keyboard_State
+_ecore_x_e_vkbd_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_ON;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_IP;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_URL;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD;
+ if (atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME)
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME;
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_x_e_vkbd_atom_get(Ecore_X_Virtual_Keyboard_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_ON:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_ALPHA:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ALPHA;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_NUMERIC:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_NUMERIC;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_PIN:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PIN;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_PHONE_NUMBER:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PHONE_NUMBER;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_HEX:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HEX;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_TERMINAL:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_TERMINAL;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_PASSWORD:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_PASSWORD;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_IP:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_IP;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_HOST:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_HOST;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_FILE:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_FILE;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_URL:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_URL;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_KEYPAD:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_KEYPAD;
+ case ECORE_X_VIRTUAL_KEYBOARD_STATE_J2ME:
+ return ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_J2ME;
+ default: return 0;
+ }
+ return 0;
+}
+
+EAPI void
+ecore_x_e_virtual_keyboard_state_set(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_vkbd_atom_get(state);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Virtual_Keyboard_State
+ecore_x_e_virtual_keyboard_state_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_atom_get(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE,
+ &atom, 1))
+ return ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN;
+ return _ecore_x_e_vkbd_state_get(atom);
+}
+
+EAPI void
+ecore_x_e_virtual_keyboard_state_send(Ecore_X_Window win, Ecore_X_Virtual_Keyboard_State state)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ _ecore_x_e_vkbd_atom_get(state),
+ 0, 0, 0, 0);
+}
+
+static Ecore_X_Atom
+_ecore_x_e_illume_atom_get(Ecore_X_Illume_Mode mode)
+{
+ switch (mode)
+ {
+ case ECORE_X_ILLUME_MODE_SINGLE:
+ return ECORE_X_ATOM_E_ILLUME_MODE_SINGLE;
+ case ECORE_X_ILLUME_MODE_DUAL_TOP:
+ return ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP;
+ case ECORE_X_ILLUME_MODE_DUAL_LEFT:
+ return ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT;
+ default:
+ return ECORE_X_ILLUME_MODE_UNKNOWN;;
+ }
+ return ECORE_X_ILLUME_MODE_UNKNOWN;
+}
+
+static Ecore_X_Illume_Mode
+_ecore_x_e_illume_mode_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_MODE_SINGLE)
+ return ECORE_X_ILLUME_MODE_SINGLE;
+ if (atom == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP)
+ return ECORE_X_ILLUME_MODE_DUAL_TOP;
+ if (atom == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT)
+ return ECORE_X_ILLUME_MODE_DUAL_LEFT;
+ return ECORE_X_ILLUME_MODE_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_zone_set(Ecore_X_Window win, Ecore_X_Window zone)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(win, ECORE_X_ATOM_E_ILLUME_ZONE,
+ &zone, 1);
+}
+
+EAPI Ecore_X_Window
+ecore_x_e_illume_zone_get(Ecore_X_Window win)
+{
+ Ecore_X_Window zone;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_window_get(win, ECORE_X_ATOM_E_ILLUME_ZONE,
+ &zone, 1)) return 0;
+ return zone;
+}
+
+EAPI void
+ecore_x_e_illume_zone_list_set(Ecore_X_Window win, Ecore_X_Window *zones, unsigned int n_zones)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(win, ECORE_X_ATOM_E_ILLUME_ZONE_LIST,
+ zones, n_zones);
+}
+
+EAPI void
+ecore_x_e_illume_conformant_set(Ecore_X_Window win, unsigned int is_conformant)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_CONFORMANT,
+ &is_conformant, 1);
+}
+
+EAPI int
+ecore_x_e_illume_conformant_get(Ecore_X_Window win)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_CONFORMANT,
+ &val, 1))
+ return 0;
+ return val;
+}
+
+EAPI void
+ecore_x_e_illume_mode_set(Ecore_X_Window win, Ecore_X_Illume_Mode mode)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_illume_atom_get(mode);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_MODE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Mode
+ecore_x_e_illume_mode_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_atom_get(win, ECORE_X_ATOM_E_ILLUME_MODE, &atom, 1))
+ return ECORE_X_ILLUME_MODE_UNKNOWN;
+ return _ecore_x_e_illume_mode_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_mode_send(Ecore_X_Window win, Ecore_X_Illume_Mode mode)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_MODE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ _ecore_x_e_illume_atom_get(mode),
+ 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_focus_back_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_FOCUS_BACK,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_focus_forward_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_focus_home_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_FOCUS_HOME,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_close_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_CLOSE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_home_new_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_HOME_NEW,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_home_del_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_HOME_DEL,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_DRAG, &drag, 1);
+}
+
+EAPI int
+ecore_x_e_illume_drag_get(Ecore_X_Window win)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_DRAG, &val, 1))
+ return 0;
+ return val;
+}
+
+EAPI void
+ecore_x_e_illume_drag_locked_set(Ecore_X_Window win, unsigned int is_locked)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED,
+ &is_locked, 1);
+}
+
+EAPI int
+ecore_x_e_illume_drag_locked_get(Ecore_X_Window win)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED,
+ &val, 1))
+ return 0;
+ return val;
+}
+
+EAPI void
+ecore_x_e_illume_drag_start_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_DRAG_START,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_drag_end_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_DRAG_END,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_indicator_geometry_set(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ geom[0] = x;
+ geom[1] = y;
+ geom[2] = w;
+ geom[3] = h;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY,
+ geom, 4);
+}
+
+EAPI int
+ecore_x_e_illume_indicator_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY,
+ geom, 4);
+ if (ret != 4) return 0;
+ if (x) *x = geom[0];
+ if (y) *y = geom[1];
+ if (w) *w = geom[2];
+ if (h) *h = geom[3];
+ return 1;
+}
+
+EAPI void
+ecore_x_e_illume_softkey_geometry_set(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ geom[0] = x;
+ geom[1] = y;
+ geom[2] = w;
+ geom[3] = h;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY,
+ geom, 4);
+}
+
+EAPI int
+ecore_x_e_illume_softkey_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY,
+ geom, 4);
+ if (ret != 4) return 0;
+ if (x) *x = geom[0];
+ if (y) *y = geom[1];
+ if (w) *w = geom[2];
+ if (h) *h = geom[3];
+ return 1;
+}
+
+EAPI void
+ecore_x_e_illume_keyboard_geometry_set(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ geom[0] = x;
+ geom[1] = y;
+ geom[2] = w;
+ geom[3] = h;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY,
+ geom, 4);
+}
+
+EAPI int
+ecore_x_e_illume_keyboard_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h)
+{
+ int ret = 0;
+ unsigned int geom[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_card32_get(win,
+ ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY,
+ geom, 4);
+ if (ret != 4) return 0;
+ if (x) *x = geom[0];
+ if (y) *y = geom[1];
+ if (w) *w = geom[2];
+ if (h) *h = geom[3];
+ return 1;
+}
+
+static Ecore_X_Atom
+_ecore_x_e_quickpanel_atom_get(Ecore_X_Illume_Quickpanel_State state)
+{
+ switch (state)
+ {
+ case ECORE_X_ILLUME_QUICKPANEL_STATE_ON:
+ return ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON;
+ case ECORE_X_ILLUME_QUICKPANEL_STATE_OFF:
+ return ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static Ecore_X_Illume_Quickpanel_State
+_ecore_x_e_quickpanel_state_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON)
+ return ECORE_X_ILLUME_QUICKPANEL_STATE_ON;
+ if (atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF)
+ return ECORE_X_ILLUME_QUICKPANEL_STATE_OFF;
+ return ECORE_X_ILLUME_QUICKPANEL_STATE_UNKNOWN;
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_set(Ecore_X_Window win, unsigned int is_quickpanel)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL,
+ &is_quickpanel, 1);
+}
+
+EAPI int
+ecore_x_e_illume_quickpanel_get(Ecore_X_Window win)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL,
+ &val, 1))
+ return 0;
+ return val;
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_state_set(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state)
+{
+ Ecore_X_Atom atom = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_e_quickpanel_atom_get(state);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE,
+ &atom, 1);
+}
+
+EAPI Ecore_X_Illume_Quickpanel_State
+ecore_x_e_illume_quickpanel_state_get(Ecore_X_Window win)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_atom_get(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE,
+ &atom, 1))
+ return ECORE_X_ILLUME_QUICKPANEL_STATE_UNKNOWN;
+ return _ecore_x_e_quickpanel_state_get(atom);
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_state_send(Ecore_X_Window win, Ecore_X_Illume_Quickpanel_State state)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ _ecore_x_e_quickpanel_atom_get(state),
+ 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_state_toggle(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win,
+ ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE_TOGGLE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 0, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_priority_major_set(Ecore_X_Window win, unsigned int priority)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win,
+ ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR,
+ &priority, 1);
+}
+
+EAPI int
+ecore_x_e_illume_quickpanel_priority_major_get(Ecore_X_Window win)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR,
+ &val, 1))
+ return 0;
+ return val;
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_priority_minor_set(Ecore_X_Window win, unsigned int priority)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win,
+ ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR,
+ &priority, 1);
+}
+
+EAPI int
+ecore_x_e_illume_quickpanel_priority_minor_get(Ecore_X_Window win)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR,
+ &val, 1))
+ return 0;
+ return val;
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_zone_set(Ecore_X_Window win, unsigned int zone)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win,
+ ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE,
+ &zone, 1);
+}
+
+EAPI int
+ecore_x_e_illume_quickpanel_zone_get(Ecore_X_Window win)
+{
+ unsigned int val = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE,
+ &val, 1))
+ return 0;
+ return val;
+}
+
+EAPI void
+ecore_x_e_illume_quickpanel_position_update_send(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win,
+ ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE,
+ ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+ 1, 0, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_e_comp_sync_counter_set(Ecore_X_Window win, Ecore_X_Sync_Counter counter)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (counter)
+ ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_SYNC_COUNTER,
+ ECORE_X_ATOM_CARDINAL, &counter, 1);
+ else
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_COMP_SYNC_COUNTER);
+}
+
+EAPI Ecore_X_Sync_Counter
+ecore_x_e_comp_sync_counter_get(Ecore_X_Window win)
+{
+ int ret = 0;
+ Ecore_X_Sync_Counter counter = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret =
+ ecore_x_window_prop_xid_get(win,
+ ECORE_X_ATOM_E_COMP_SYNC_COUNTER,
+ ECORE_X_ATOM_CARDINAL,
+ &counter, 1);
+ if (ret != 1) return 0;
+ return counter;
+}
+
+EAPI void
+ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, Eina_Bool enabled)
+{
+ Ecore_X_Window win;
+
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (enabled)
+ {
+ win = ecore_x_window_new(root, 1, 2, 3, 4);
+ ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED,
+ ECORE_X_ATOM_WINDOW, &win, 1);
+ ecore_x_window_prop_xid_set(root, ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED,
+ ECORE_X_ATOM_WINDOW, &win, 1);
+ }
+ else
+ {
+ int ret;
+
+ ret =
+ ecore_x_window_prop_xid_get(root,
+ ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED,
+ ECORE_X_ATOM_WINDOW,
+ &win, 1);
+ if ((ret == 1) && (win))
+ {
+ ecore_x_window_prop_property_del(root, ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED);
+ ecore_x_window_free(win);
+ }
+ }
+}
+
+EAPI Eina_Bool
+ecore_x_e_comp_sync_supported_get(Ecore_X_Window root)
+{
+ Ecore_X_Window win, win2;
+ int ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+ ret =
+ ecore_x_window_prop_xid_get(root,
+ ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED,
+ ECORE_X_ATOM_WINDOW,
+ &win, 1);
+ if ((ret == 1) && (win))
+ {
+ ret =
+ ecore_x_window_prop_xid_get(win,
+ ECORE_X_ATOM_E_COMP_SYNC_SUPPORTED,
+ ECORE_X_ATOM_WINDOW,
+ &win2, 1);
+ if ((ret == 1) && (win2 == win))
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+EAPI void
+ecore_x_e_comp_sync_begin_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_BEGIN;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_sync_end_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_END;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_SYNC_CANCEL;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_flush_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_FLUSH;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+EAPI void
+ecore_x_e_comp_dump_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_E_COMP_DUMP;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = win;
+ xev.xclient.data.l[1] = 0; // later
+ xev.xclient.data.l[2] = 0; // later
+ xev.xclient.data.l[3] = 0; // later
+ xev.xclient.data.l[4] = 0; // later
+
+ XSendEvent(_ecore_x_disp, win, False,
+ NoEventMask, //SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static void _ecore_x_error_handle(Display * d, XErrorEvent * ev);
+static int _ecore_x_io_error_handle(Display *d);
+
+static void (*_error_func) (void *data) = NULL;
+static void *_error_data = NULL;
+static void (*_io_error_func) (void *data) = NULL;
+static void *_io_error_data = NULL;
+static int _error_request_code = 0;
+static int _error_code = 0;
+
+/**
+ * Set the error handler.
+ * @param func The error handler function
+ * @param data The data to be passed to the handler function
+ *
+ * Set the X error handler function
+ */
+EAPI void
+ecore_x_error_handler_set(void (*func) (void *data), const void *data)
+{
+ _error_func = func;
+ _error_data = (void *)data;
+}
+
+/**
+ * Set the I/O error handler.
+ * @param func The I/O error handler function
+ * @param data The data to be passed to the handler function
+ *
+ * Set the X I/O error handler function
+ */
+EAPI void
+ecore_x_io_error_handler_set(void (*func) (void *data), const void *data)
+{
+ _io_error_func = func;
+ _io_error_data = (void *)data;
+}
+
+/**
+ * Get the request code that caused the error.
+ * @return The request code causing the X error
+ *
+ * Return the X request code that caused the last X error
+ */
+EAPI int
+ecore_x_error_request_get(void)
+{
+ return _error_request_code;
+}
+
+/**
+ * Get the error code from the error.
+ * @return The error code from the X error
+ *
+ * Return the error code from the last X error
+ */
+EAPI int
+ecore_x_error_code_get(void)
+{
+ return _error_code;
+}
+
+void
+_ecore_x_error_handler_init(void)
+{
+ XSetErrorHandler((XErrorHandler)_ecore_x_error_handle);
+ XSetIOErrorHandler((XIOErrorHandler)_ecore_x_io_error_handle);
+}
+
+static void
+_ecore_x_error_handle(Display *d, XErrorEvent *ev)
+{
+ if (d == _ecore_x_disp)
+ {
+ _error_request_code = ev->request_code;
+ _error_code = ev->error_code;
+ if (_error_func) _error_func(_error_data);
+ }
+}
+
+static int
+_ecore_x_io_error_handle(Display *d)
+{
+ if (d == _ecore_x_disp)
+ {
+ if (_io_error_func) _io_error_func(_io_error_data);
+ else exit(-1);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <langinfo.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+/** OpenBSD does not define CODESET
+ * FIXME ??
+ */
+
+#ifndef CODESET
+#define CODESET "INVALID"
+#endif
+
+#if 0
+static void _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_title_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev);
+static void _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev);
+#endif
+
+static Window _ecore_x_mouse_down_last_win = 0;
+static Window _ecore_x_mouse_down_last_last_win = 0;
+static Window _ecore_x_mouse_down_last_event_win = 0;
+static Window _ecore_x_mouse_down_last_last_event_win = 0;
+static Time _ecore_x_mouse_down_last_time = 0;
+static Time _ecore_x_mouse_down_last_last_time = 0;
+static int _ecore_x_mouse_up_count = 0;
+static int _ecore_x_mouse_down_did_triple = 0;
+static int _ecore_x_last_event_mouse_move = 0;
+static Ecore_Event *_ecore_x_last_event_mouse_move_event = NULL;
+
+static void
+_ecore_x_event_free_mouse_move(void *data __UNUSED__, void *ev)
+{
+ Ecore_Event_Mouse_Move *e;
+
+ e = ev;
+ if (_ecore_x_last_event_mouse_move)
+ {
+ _ecore_x_last_event_mouse_move_event = NULL;
+ _ecore_x_last_event_mouse_move = 0;
+ }
+ free(e);
+}
+
+EAPI void
+ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask)
+{
+ XWindowAttributes attr;
+ XSetWindowAttributes s_attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!w) w = DefaultRootWindow(_ecore_x_disp);
+ memset(&attr, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(_ecore_x_disp, w, &attr);
+ s_attr.event_mask = mask | attr.your_event_mask;
+ XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
+}
+
+EAPI void
+ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask)
+{
+ XWindowAttributes attr;
+ XSetWindowAttributes s_attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!w) w = DefaultRootWindow(_ecore_x_disp);
+ memset(&attr, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(_ecore_x_disp, w, &attr);
+ s_attr.event_mask = attr.your_event_mask & ~mask;
+ XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
+}
+
+#if 0
+static void
+_ecore_x_event_free_window_prop_name_class_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Name_Class_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ if (e->clas) free(e->clas);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_title_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Title_Change *e;
+
+ e = ev;
+ if (e->title) free(e->title);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
+
+ e = ev;
+ if (e->title) free(e->title);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev)
+{
+ Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
+
+ e = ev;
+ if (e->name) free(e->name);
+ free(e);
+}
+#endif
+
+static void
+_ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Xdnd_Enter *e;
+ int i;
+
+ e = ev;
+ for (i = 0; i < e->num_types; i++)
+ XFree(e->types[i]);
+ free(e->types);
+ free(e);
+}
+
+static void
+_ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev)
+{
+ Ecore_X_Event_Selection_Notify *e;
+ Ecore_X_Selection_Data *sel;
+
+ e = ev;
+ sel = e->data;
+ if (sel->free) sel->free(sel);
+ free(e->target);
+ free(e);
+}
+
+static unsigned int
+_ecore_x_event_modifiers(unsigned int state)
+{
+ unsigned int modifiers = 0;
+
+ if (state & ECORE_X_MODIFIER_SHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (state & ECORE_X_MODIFIER_CTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if (state & ECORE_X_MODIFIER_ALT) modifiers |= ECORE_EVENT_MODIFIER_ALT;
+ if (state & ECORE_X_MODIFIER_WIN) modifiers |= ECORE_EVENT_MODIFIER_WIN;
+ if (state & ECORE_X_LOCK_SCROLL) modifiers |= ECORE_EVENT_LOCK_SCROLL;
+ if (state & ECORE_X_LOCK_NUM) modifiers |= ECORE_EVENT_LOCK_NUM;
+ if (state & ECORE_X_LOCK_CAPS) modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ return modifiers;
+}
+
+void
+_ecore_mouse_move(unsigned int timestamp, unsigned int xmodifiers,
+ int x, int y,
+ int x_root, int y_root,
+ unsigned int event_window,
+ unsigned int window,
+ unsigned int root_win,
+ int same_screen,
+ int dev, double radx, double rady, double pressure, double angle, double mx, double my, double mrx, double mry)
+{
+ Ecore_Event_Mouse_Move *e;
+ Ecore_Event *event;
+
+ e = malloc(sizeof(Ecore_Event_Mouse_Move));
+ if (!e) return ;
+
+ e->window = window;
+ e->root_window = root_win;
+ e->timestamp = timestamp;
+ e->same_screen = same_screen;
+ e->event_window = event_window;
+
+ e->modifiers = _ecore_x_event_modifiers(xmodifiers);
+ e->x = x;
+ e->y = y;
+ e->root.x = x_root;
+ e->root.y = y_root;
+
+ e->multi.device = dev;
+ e->multi.radius = (radx + rady) / 2;
+ e->multi.radius_x = radx;
+ e->multi.radius_y = rady;
+ e->multi.pressure = pressure;
+ e->multi.angle = angle;
+ e->multi.x = mx;
+ e->multi.y = my;
+ e->multi.root.x = mrx;
+ e->multi.root.y = mry;
+
+ event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _ecore_x_event_free_mouse_move, NULL);
+
+ _ecore_x_event_last_time = timestamp;
+ _ecore_x_event_last_win = window;
+ _ecore_x_event_last_root_x = x_root;
+ _ecore_x_event_last_root_y = y_root;
+
+ _ecore_x_last_event_mouse_move_event = event;
+}
+
+static void
+_ecore_key_press(int event, XKeyEvent *xevent)
+{
+ Ecore_Event_Key *e;
+ char *compose = NULL;
+ char *tmp = NULL;
+ char *keyname;
+ char *key;
+ char keyname_buffer[256];
+ char compose_buffer[256];
+ KeySym sym;
+ XComposeStatus status;
+ int val;
+
+ _ecore_x_last_event_mouse_move = 0;
+ keyname = XKeysymToString(XKeycodeToKeysym(xevent->display,
+ xevent->keycode, 0));
+ if (!keyname)
+ {
+ snprintf(keyname_buffer, sizeof(keyname_buffer), "Keycode-%i", xevent->keycode);
+ keyname = keyname_buffer;
+ if (!keyname) return ;
+ }
+
+ sym = 0;
+ key = NULL;
+ compose = NULL;
+ if (_ecore_x_ic)
+ {
+ Status mbstatus;
+#ifdef X_HAVE_UTF8_STRING
+ val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus);
+#else
+ val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus);
+#endif
+ if (mbstatus == XBufferOverflow)
+ {
+ tmp = malloc(sizeof (char) * (val + 1));
+ if (!tmp) return ;
+
+ compose = tmp;
+
+#ifdef X_HAVE_UTF8_STRING
+ val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus);
+#else
+ val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus);
+#endif
+ if (val > 0)
+ {
+ tmp[val] = 0;
+
+#ifndef X_HAVE_UTF8_STRING
+ compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", tmp);
+ free(tmp);
+ tmp = compose;
+#endif
+ }
+ else compose = NULL;
+ }
+ else
+ if (val > 0)
+ {
+ compose_buffer[val] = 0;
+#ifdef X_HAVE_UTF8_STRING
+ compose = compose_buffer;
+#else
+ compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
+ tmp = compose;
+#endif
+ }
+ }
+ else
+ {
+ val = XLookupString(xevent, compose_buffer, sizeof(compose_buffer), &sym, &status);
+ if (val > 0)
+ {
+ compose_buffer[val] = 0;
+ compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
+ tmp = compose;
+ }
+ }
+
+ key = XKeysymToString(sym);
+ if (!key) key = keyname;
+ if (!key) goto on_error;
+
+ e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + (compose ? strlen(compose) : 0) + 3);
+ if (!e) goto on_error;
+
+ e->keyname = (char*) (e + 1);
+ e->key = e->keyname + strlen(keyname) + 1;
+ e->compose = (compose) ? e->key + strlen(key) + 1 : NULL;
+ e->string = e->compose;
+
+ strcpy((char *) e->keyname, keyname);
+ strcpy((char *) e->key, key);
+ if (compose) strcpy((char *) e->compose, compose);
+
+ e->modifiers = _ecore_x_event_modifiers(xevent->state);
+
+ e->timestamp = xevent->time;
+ e->window = xevent->subwindow ? xevent->subwindow : xevent->window;
+ e->event_window = xevent->window;
+ e->same_screen = xevent->same_screen;
+ e->root_window = xevent->root;
+
+ ecore_event_add(event, e, NULL, NULL);
+
+ _ecore_x_event_last_time = e->timestamp;
+
+ on_error:
+ if (tmp) free(tmp);
+}
+
+Ecore_Event_Mouse_Button *
+_ecore_mouse_button(int event,
+ unsigned int timestamp, unsigned int xmodifiers,
+ unsigned int buttons,
+ int x, int y,
+ int x_root, int y_root,
+ unsigned int event_window,
+ unsigned int window,
+ unsigned int root_win,
+ int same_screen,
+ int dev, double radx, double rady, double pressure, double angle, double mx, double my, double mrx, double mry)
+{
+ Ecore_Event_Mouse_Button *e;
+
+ e = malloc(sizeof(Ecore_Event_Mouse_Button));
+ if (!e) return NULL;
+
+ e->window = window;
+ e->root_window = root_win;
+ e->timestamp = timestamp;
+ e->same_screen = same_screen;
+ e->event_window = event_window;
+
+ e->buttons = buttons;
+ e->modifiers = _ecore_x_event_modifiers(xmodifiers);
+ e->double_click = 0;
+ e->triple_click = 0;
+ e->x = x;
+ e->y = y;
+ e->root.x = x_root;
+ e->root.y = y_root;
+
+ if (event_window == window)
+ {
+ if (((int)(timestamp - _ecore_x_mouse_down_last_time) <=
+ (int)(1000 * _ecore_x_double_click_time)) &&
+ (window == _ecore_x_mouse_down_last_win) &&
+ (event_window == _ecore_x_mouse_down_last_event_win)
+ )
+ e->double_click = 1;
+ if (((int)(timestamp - _ecore_x_mouse_down_last_last_time) <=
+ (int)(2 * 1000 * _ecore_x_double_click_time)) &&
+ (window == _ecore_x_mouse_down_last_win) &&
+ (window == _ecore_x_mouse_down_last_last_win) &&
+ (event_window == _ecore_x_mouse_down_last_event_win) &&
+ (event_window == _ecore_x_mouse_down_last_last_event_win)
+ )
+ {
+ e->triple_click = 1;
+ _ecore_x_mouse_down_did_triple = 1;
+ }
+ else
+ _ecore_x_mouse_down_did_triple = 0;
+ }
+
+ if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN
+ && !e->double_click
+ && !e->triple_click)
+ _ecore_x_mouse_up_count = 0;
+
+ e->multi.device = dev;
+ e->multi.radius = (radx + rady) / 2;
+ e->multi.radius_x = radx;
+ e->multi.radius_y = rady;
+ e->multi.pressure = pressure;
+ e->multi.angle = angle;
+ e->multi.x = mx;
+ e->multi.y = my;
+ e->multi.root.x = mrx;
+ e->multi.root.y = mry;
+
+ _ecore_x_event_last_time = e->timestamp;
+ _ecore_x_event_last_win = e->window;
+ _ecore_x_event_last_root_x = x_root;
+ _ecore_x_event_last_root_y = y_root;
+
+ ecore_event_add(event, e, NULL, NULL);
+
+ return e;
+}
+
+void
+_ecore_x_event_handle_any_event(XEvent *xevent)
+{
+ XEvent* ev = malloc(sizeof(XEvent));
+
+ memcpy(ev, xevent, sizeof(XEvent));
+ ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_key_press(XEvent *xevent)
+{
+ _ecore_key_press(ECORE_EVENT_KEY_DOWN, (XKeyEvent *) xevent);
+}
+
+void
+_ecore_x_event_handle_key_release(XEvent *xevent)
+{
+ _ecore_key_press(ECORE_EVENT_KEY_UP, (XKeyEvent *) xevent);
+}
+
+void
+_ecore_x_event_handle_button_press(XEvent *xevent)
+{
+ int i;
+
+ _ecore_x_last_event_mouse_move = 0;
+ if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 8))
+ {
+ Ecore_Event_Mouse_Wheel *e;
+
+ e = malloc(sizeof(Ecore_Event_Mouse_Wheel));
+ if (!e) return;
+
+ e->timestamp = xevent->xbutton.time;
+ e->modifiers = _ecore_x_event_modifiers(xevent->xbutton.state);
+ switch (xevent->xbutton.button)
+ {
+ case 4: e->direction = 0; e->z = -1; break;
+ case 5: e->direction = 0; e->z = 1; break;
+ case 6: e->direction = 1; e->z = -1; break;
+ case 7: e->direction = 1; e->z = 1; break;
+ default: e->direction = 0; e->z = 0; break;
+ }
+
+ e->x = xevent->xbutton.x;
+ e->y = xevent->xbutton.y;
+ e->root.x = xevent->xbutton.x_root;
+ e->root.y = xevent->xbutton.y_root;
+
+ if (xevent->xbutton.subwindow) e->window = xevent->xbutton.subwindow;
+ else e->window = xevent->xbutton.window;
+ e->event_window = xevent->xbutton.window;
+ e->same_screen = xevent->xbutton.same_screen;
+ e->root_window = xevent->xbutton.root;
+
+ _ecore_x_event_last_time = e->timestamp;
+ _ecore_x_event_last_win = e->window;
+ _ecore_x_event_last_root_x = xevent->xbutton.x_root;
+ _ecore_x_event_last_root_y = xevent->xbutton.y_root;
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
+
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
+ (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
+ {
+ int replay = 0;
+
+ if (_ecore_window_grab_replay_func)
+ replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
+ ECORE_EVENT_MOUSE_WHEEL,
+ e);
+ if (replay)
+ XAllowEvents(xevent->xbutton.display,
+ ReplayPointer, xevent->xbutton.time);
+ else
+ XAllowEvents(xevent->xbutton.display,
+ AsyncPointer, xevent->xbutton.time);
+ break;
+ }
+ }
+ }
+ else
+ {
+ {
+ _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root,
+ xevent->xbutton.window,
+ (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->xbutton.window),
+ xevent->xbutton.root,
+ xevent->xbutton.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root);
+ }
+ {
+ Ecore_Event_Mouse_Button *e;
+ int event_window;
+ int window;
+
+ if (_ecore_x_mouse_down_did_triple)
+ {
+ _ecore_x_mouse_down_last_win = 0;
+ _ecore_x_mouse_down_last_last_win = 0;
+ _ecore_x_mouse_down_last_event_win = 0;
+ _ecore_x_mouse_down_last_last_event_win = 0;
+ _ecore_x_mouse_down_last_time = 0;
+ _ecore_x_mouse_down_last_last_time = 0;
+ }
+
+ window = (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->xbutton.window);
+ event_window = xevent->xbutton.window;
+
+ e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ xevent->xbutton.time, xevent->xbutton.state,
+ xevent->xbutton.button,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root,
+ event_window, window,
+ xevent->xbutton.root, xevent->xbutton.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root);
+ if (e)
+ for (i = 0; i < _ecore_window_grabs_num; i++)
+ {
+ if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
+ (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
+ {
+ int replay = 0;
+
+ if (_ecore_window_grab_replay_func)
+ replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
+ ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ e);
+ if (replay)
+ XAllowEvents(xevent->xbutton.display,
+ ReplayPointer, xevent->xbutton.time);
+ else
+ XAllowEvents(xevent->xbutton.display,
+ AsyncPointer, xevent->xbutton.time);
+ break;
+ }
+ }
+
+ if (window == event_window)
+ {
+ if (!_ecore_x_mouse_down_did_triple)
+ {
+ _ecore_x_mouse_down_last_last_win = _ecore_x_mouse_down_last_win;
+ if (xevent->xbutton.subwindow)
+ _ecore_x_mouse_down_last_win = xevent->xbutton.subwindow;
+ else
+ _ecore_x_mouse_down_last_win = xevent->xbutton.window;
+ _ecore_x_mouse_down_last_last_event_win = _ecore_x_mouse_down_last_event_win;
+ _ecore_x_mouse_down_last_event_win = xevent->xbutton.window;
+ _ecore_x_mouse_down_last_last_time = _ecore_x_mouse_down_last_time;
+ _ecore_x_mouse_down_last_time = xevent->xbutton.time;
+ }
+ }
+ }
+ }
+}
+
+void
+_ecore_x_event_handle_button_release(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* filter out wheel buttons */
+ if ((xevent->xbutton.button <= 3) || (xevent->xbutton.button > 7))
+ {
+ _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root,
+ xevent->xbutton.window,
+ (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->xbutton.window),
+ xevent->xbutton.root,
+ xevent->xbutton.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root);
+
+ _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
+ xevent->xbutton.time, xevent->xbutton.state,
+ xevent->xbutton.button,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root,
+ xevent->xbutton.window,
+ (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->xbutton.window),
+ xevent->xbutton.root,
+ xevent->xbutton.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.x_root, xevent->xbutton.y_root);
+ }
+}
+
+void
+_ecore_x_event_handle_motion_notify(XEvent *xevent)
+{
+/*
+ if (_ecore_x_last_event_mouse_move)
+ {
+ ecore_event_del(_ecore_x_last_event_mouse_move_event);
+ _ecore_x_last_event_mouse_move = 0;
+ _ecore_x_last_event_mouse_move_event = NULL;
+ }
+ */
+ _ecore_mouse_move(xevent->xmotion.time, xevent->xmotion.state,
+ xevent->xmotion.x, xevent->xmotion.y,
+ xevent->xmotion.x_root, xevent->xmotion.y_root,
+ xevent->xmotion.window,
+ (xevent->xmotion.subwindow ? xevent->xmotion.subwindow : xevent->xmotion.window),
+ xevent->xmotion.root,
+ xevent->xmotion.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xmotion.x, xevent->xmotion.y,
+ xevent->xmotion.x_root, xevent->xmotion.y_root);
+
+ _ecore_x_last_event_mouse_move = 1;
+
+ /* Xdnd handling */
+ _ecore_x_dnd_drag(xevent->xmotion.root, xevent->xmotion.x_root, xevent->xmotion.y_root);
+}
+
+void
+_ecore_x_event_handle_enter_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ {
+ _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root,
+ xevent->xcrossing.window,
+ (xevent->xcrossing.subwindow ? xevent->xcrossing.subwindow : xevent->xcrossing.window),
+ xevent->xcrossing.root,
+ xevent->xcrossing.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root);
+ }
+ {
+ Ecore_X_Event_Mouse_In *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
+ if (!e) return;
+ e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow;
+ else e->win = xevent->xcrossing.window;
+ e->same_screen = xevent->xcrossing.same_screen;
+ e->root_win = xevent->xcrossing.root;
+ e->event_win = xevent->xcrossing.window;
+
+ if (xevent->xcrossing.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xcrossing.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xcrossing.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xcrossing.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xcrossing.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xcrossing.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xcrossing.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_leave_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ {
+ _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root,
+ xevent->xcrossing.window,
+ (xevent->xcrossing.subwindow ? xevent->xcrossing.subwindow : xevent->xcrossing.window),
+ xevent->xcrossing.root,
+ xevent->xcrossing.same_screen,
+ 0, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ xevent->xcrossing.x, xevent->xcrossing.y,
+ xevent->xcrossing.x_root, xevent->xcrossing.y_root);
+ }
+ {
+ Ecore_X_Event_Mouse_Out *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
+ if (!e) return;
+ e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
+ e->x = xevent->xcrossing.x;
+ e->y = xevent->xcrossing.y;
+ e->root.x = xevent->xcrossing.x_root;
+ e->root.y = xevent->xcrossing.y_root;
+ if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow;
+ else e->win = xevent->xcrossing.window;
+ e->same_screen = xevent->xcrossing.same_screen;
+ e->root_win = xevent->xcrossing.root;
+ e->event_win = xevent->xcrossing.window;
+
+ if (xevent->xcrossing.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xcrossing.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xcrossing.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xcrossing.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xcrossing.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xcrossing.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xcrossing.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+
+ e->time = xevent->xcrossing.time;
+ _ecore_x_event_last_time = e->time;
+ _ecore_x_event_last_win = e->win;
+ _ecore_x_event_last_root_x = e->root.x;
+ _ecore_x_event_last_root_y = e->root.y;
+ ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_focus_in(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Focus_In *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ if (_ecore_x_ic)
+ {
+ char *str;
+
+ XSetICValues(_ecore_x_ic, XNFocusWindow, xevent->xfocus.window, NULL);
+ if ((str = XmbResetIC(_ecore_x_ic)))
+ XFree(str);
+ XSetICFocus(_ecore_x_ic);
+ }
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
+ if (!e) return;
+ e->win = xevent->xfocus.window;
+
+ if (xevent->xfocus.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xfocus.mode == NotifyWhileGrabbed)
+ e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ else if (xevent->xfocus.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xfocus.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xfocus.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xfocus.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xfocus.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyPointer)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ else if (xevent->xfocus.detail == NotifyPointerRoot)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ else if (xevent->xfocus.detail == NotifyDetailNone)
+ e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+
+ e->time = _ecore_x_event_last_time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_focus_out(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Focus_Out *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ if (_ecore_x_ic) XUnsetICFocus(_ecore_x_ic);
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
+ if (!e) return;
+ e->win = xevent->xfocus.window;
+
+ if (xevent->xfocus.mode == NotifyNormal)
+ e->mode = ECORE_X_EVENT_MODE_NORMAL;
+ else if (xevent->xfocus.mode == NotifyWhileGrabbed)
+ e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
+ else if (xevent->xfocus.mode == NotifyGrab)
+ e->mode = ECORE_X_EVENT_MODE_GRAB;
+ else if (xevent->xfocus.mode == NotifyUngrab)
+ e->mode = ECORE_X_EVENT_MODE_UNGRAB;
+
+ if (xevent->xfocus.detail == NotifyAncestor)
+ e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
+ else if (xevent->xfocus.detail == NotifyVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyInferior)
+ e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
+ else if (xevent->xfocus.detail == NotifyNonlinear)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
+ else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
+ e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
+ else if (xevent->xfocus.detail == NotifyPointer)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER;
+ else if (xevent->xfocus.detail == NotifyPointerRoot)
+ e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
+ else if (xevent->xfocus.detail == NotifyDetailNone)
+ e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
+
+ e->time = _ecore_x_event_last_time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_keymap_notify(XEvent *xevent __UNUSED__)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_expose(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Damage *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e) return;
+ e->win = xevent->xexpose.window;
+ e->time = _ecore_x_event_last_time;
+ e->x = xevent->xexpose.x;
+ e->y = xevent->xexpose.y;
+ e->w = xevent->xexpose.width;
+ e->h = xevent->xexpose.height;
+ e->count = xevent->xexpose.count;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_graphics_expose(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Damage *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
+ if (!e) return;
+ e->win = xevent->xgraphicsexpose.drawable;
+ e->time = _ecore_x_event_last_time;
+ e->x = xevent->xgraphicsexpose.x;
+ e->y = xevent->xgraphicsexpose.y;
+ e->w = xevent->xgraphicsexpose.width;
+ e->h = xevent->xgraphicsexpose.height;
+ e->count = xevent->xgraphicsexpose.count;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_visibility_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+// if (xevent->xvisibility.state != VisibilityPartiallyObscured)
+ {
+ Ecore_X_Event_Window_Visibility_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
+ if (!e) return;
+ e->win = xevent->xvisibility.window;
+ e->time = _ecore_x_event_last_time;
+ if (xevent->xvisibility.state == VisibilityFullyObscured)
+ e->fully_obscured = 1;
+ else
+ e->fully_obscured = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_create_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Create *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
+ if (!e) return;
+ e->win = xevent->xcreatewindow.window;
+ e->parent = xevent->xcreatewindow.parent;
+ if (xevent->xcreatewindow.override_redirect)
+ e->override = 1;
+ else
+ e->override = 0;
+ e->x = xevent->xcreatewindow.x;
+ e->y = xevent->xcreatewindow.y;
+ e->w = xevent->xcreatewindow.width;
+ e->h = xevent->xcreatewindow.height;
+ e->border = xevent->xcreatewindow.border_width;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_destroy_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Destroy *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
+ if (!e) return;
+ e->win = xevent->xdestroywindow.window;
+ e->event_win = xevent->xdestroywindow.event;
+ e->time = _ecore_x_event_last_time;
+ if (e->win == _ecore_x_event_last_win) _ecore_x_event_last_win = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_unmap_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Hide *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
+ if (!e) return;
+ e->win = xevent->xunmap.window;
+ e->event_win = xevent->xunmap.event;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_map_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Show *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
+ if (!e) return;
+ e->win = xevent->xmap.window;
+ e->event_win = xevent->xmap.event;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_map_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Show_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
+ if (!e) return;
+ e->win = xevent->xmaprequest.window;
+ e->time = _ecore_x_event_last_time;
+ e->parent = xevent->xmaprequest.parent;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_reparent_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Reparent *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
+ if (!e) return;
+ e->win = xevent->xreparent.window;
+ e->event_win = xevent->xreparent.event;
+ e->parent = xevent->xreparent.parent;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_configure_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Configure *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
+ if (!e) return;
+ e->win = xevent->xconfigure.window;
+ e->event_win = xevent->xconfigure.event;
+ e->abovewin = xevent->xconfigure.above;
+ e->x = xevent->xconfigure.x;
+ e->y = xevent->xconfigure.y;
+ e->w = xevent->xconfigure.width;
+ e->h = xevent->xconfigure.height;
+ e->border = xevent->xconfigure.border_width;
+ e->override = xevent->xconfigure.override_redirect;
+ e->from_wm = xevent->xconfigure.send_event;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_configure_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Configure_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
+ if (!e) return;
+ e->win = xevent->xconfigurerequest.window;
+ e->parent_win = xevent->xconfigurerequest.parent;
+ e->abovewin = xevent->xconfigurerequest.above;
+ e->x = xevent->xconfigurerequest.x;
+ e->y = xevent->xconfigurerequest.y;
+ e->w = xevent->xconfigurerequest.width;
+ e->h = xevent->xconfigurerequest.height;
+ e->border = xevent->xconfigurerequest.border_width;
+ e->value_mask = xevent->xconfigurerequest.value_mask;
+ e->time = _ecore_x_event_last_time;
+
+ if (xevent->xconfigurerequest.detail == Above)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else if (xevent->xconfigurerequest.detail == Below)
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ else if (xevent->xconfigurerequest.detail == TopIf)
+ e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
+ else if (xevent->xconfigurerequest.detail == BottomIf)
+ e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
+ else if (xevent->xconfigurerequest.detail == Opposite)
+ e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_gravity_notify(XEvent *xevent __UNUSED__)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* FIXME: handle this event type */
+}
+
+void
+_ecore_x_event_handle_resize_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Resize_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
+ if (!e) return;
+ e->win = xevent->xresizerequest.window;
+ e->w = xevent->xresizerequest.width;
+ e->h = xevent->xresizerequest.height;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_circulate_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Stack *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
+ if (!e) return;
+ e->win = xevent->xcirculate.window;
+ e->event_win = xevent->xcirculate.event;
+ if (xevent->xcirculate.place == PlaceOnTop)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_circulate_request(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Stack_Request *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
+ if (!e) return;
+ e->win = xevent->xcirculaterequest.window;
+ e->parent = xevent->xcirculaterequest.parent;
+ if (xevent->xcirculaterequest.place == PlaceOnTop)
+ e->detail = ECORE_X_WINDOW_STACK_ABOVE;
+ else
+ e->detail = ECORE_X_WINDOW_STACK_BELOW;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_property_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+#if 0 /* for now i disabled this. nice idea though this is - it leaves a lot
+ * to be desired for efficiency that is better left to the app layer
+ */
+ if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS)
+ {
+ Ecore_X_Event_Window_Prop_Name_Class_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change));
+ if (!e) return;
+ ecore_x_window_prop_name_class_get(xevent->xproperty.window,
+ &(e->name), &(e->clas));
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e,
+ _ecore_x_event_free_window_prop_name_class_change, NULL);
+ }
+ else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) ||
+ (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME))
+ {
+ Ecore_X_Event_Window_Prop_Title_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change));
+ if (!e) return;
+ e->title = ecore_x_window_prop_title_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e,
+ _ecore_x_event_free_window_prop_title_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME)
+ {
+ Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change));
+ if (!e) return;
+ e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e,
+ _ecore_x_event_free_window_prop_visible_title_change, NULL);
+ }
+ else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) ||
+ (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME))
+ {
+ Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e,
+ _ecore_x_event_free_window_prop_icon_name_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME)
+ {
+ Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e,
+ _ecore_x_event_free_window_prop_visible_icon_name_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
+ {
+ Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change));
+ if (!e) return;
+ e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e,
+ _ecore_x_event_free_window_prop_client_machine_change, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID)
+ {
+ Ecore_X_Event_Window_Prop_Pid_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change));
+ if (!e) return;
+ e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window);
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
+ }
+ else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP)
+ {
+ Ecore_X_Event_Window_Prop_Desktop_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change));
+ if (!e) return;
+ e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window);
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
+ }
+ else
+#endif
+ {
+ Ecore_X_Event_Window_Property *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Property));
+ if (!e) return;
+ e->win = xevent->xproperty.window;
+ e->atom = xevent->xproperty.atom;
+ e->time = xevent->xproperty.time;
+ _ecore_x_event_last_time = e->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_selection_clear(XEvent *xevent)
+{
+ Ecore_X_Selection_Intern *d;
+ Ecore_X_Event_Selection_Clear *e;
+ Ecore_X_Atom sel;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_last_event_mouse_move = 0;
+ d = _ecore_x_selection_get(xevent->xselectionclear.selection);
+ if (d && (xevent->xselectionclear.time > d->time))
+ {
+ _ecore_x_selection_set(None, NULL, 0,
+ xevent->xselectionclear.selection);
+ }
+
+ /* Generate event for app cleanup */
+ e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
+ e->win = xevent->xselectionclear.window;
+ e->time = xevent->xselectionclear.time;
+ e->atom = sel = xevent->xselectionclear.selection;
+ if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+ ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_selection_request(XEvent *xevent)
+{
+ Ecore_X_Event_Selection_Request *e;
+ Ecore_X_Selection_Intern *sd;
+ void *data;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_last_event_mouse_move = 0;
+ /*
+ * Generate a selection request event.
+ */
+ e = malloc(sizeof(Ecore_X_Event_Selection_Request));
+ e->owner = xevent->xselectionrequest.owner;
+ e->requestor = xevent->xselectionrequest.requestor;
+ e->time = xevent->xselectionrequest.time;
+ e->selection = xevent->xselectionrequest.selection;
+ e->target = xevent->xselectionrequest.target;
+ e->property = xevent->xselectionrequest.property;
+ ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);
+
+ if ((sd = _ecore_x_selection_get(xevent->xselectionrequest.selection)) &&
+ (sd->win == xevent->xselectionrequest.owner))
+ {
+ Ecore_X_Selection_Intern *si;
+
+ si = _ecore_x_selection_get(xevent->xselectionrequest.selection);
+ if (si->data)
+ {
+ Ecore_X_Atom property;
+
+ if (!ecore_x_selection_convert(xevent->xselectionrequest.selection,
+ xevent->xselectionrequest.target,
+ &data))
+ {
+ /* Refuse selection, conversion to requested target failed */
+ property = None;
+ }
+ else
+ {
+ /* FIXME: This does not properly handle large data transfers */
+ ecore_x_window_prop_property_set(xevent->xselectionrequest.requestor,
+ xevent->xselectionrequest.property,
+ xevent->xselectionrequest.target,
+ 8, data, sd->length);
+ property = xevent->xselectionrequest.property;
+ free(data);
+ }
+
+ ecore_x_selection_notify_send(xevent->xselectionrequest.requestor,
+ xevent->xselectionrequest.selection,
+ xevent->xselectionrequest.target,
+ property,
+ xevent->xselectionrequest.time);
+ }
+ }
+ return;
+}
+
+void
+_ecore_x_event_handle_selection_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Selection_Notify *e;
+ unsigned char *data = NULL;
+ Ecore_X_Atom selection;
+ int num_ret, format;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_last_event_mouse_move = 0;
+ selection = xevent->xselection.selection;
+
+ if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS)
+ {
+ format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
+ xevent->xselection.property,
+ XA_ATOM, 32, &data, &num_ret);
+ if (!format) return;
+ }
+ else
+ {
+ format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
+ xevent->xselection.property,
+ AnyPropertyType, 8, &data,
+ &num_ret);
+ if (!format) return;
+ }
+
+ e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
+ if (!e) return;
+ e->win = xevent->xselection.requestor;
+ e->time = xevent->xselection.time;
+ e->atom = selection;
+ e->target = _ecore_x_selection_target_get(xevent->xselection.target);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ e->selection = ECORE_X_SELECTION_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ e->selection = ECORE_X_SELECTION_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ e->selection = ECORE_X_SELECTION_XDND;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ e->selection = ECORE_X_SELECTION_CLIPBOARD;
+ else
+ e->selection = ECORE_X_SELECTION_OTHER;
+
+ e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
+
+ ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
+ _ecore_x_event_free_selection_notify, NULL);
+}
+
+void
+_ecore_x_event_handle_colormap_notify(XEvent *xevent)
+{
+ Ecore_X_Event_Window_Colormap *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap));
+ if (!e) return;
+ e->win = xevent->xcolormap.window;
+ e->cmap = xevent->xcolormap.colormap;
+ e->time = _ecore_x_event_last_time;
+ if (xevent->xcolormap.state == ColormapInstalled)
+ e->installed = 1;
+ else
+ e->installed = 0;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_client_message(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* Special client message event handling here. need to put LOTS of if */
+ /* checks here and generate synthetic events per special message known */
+ /* otherwise generate generic client message event. this would handle*/
+ /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
+ if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
+ (xevent->xclient.format == 32) &&
+ (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW))
+ {
+ Ecore_X_Event_Window_Delete_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->time = _ecore_x_event_last_time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
+ }
+
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
+ (xevent->xclient.format == 32) &&
+ /* Ignore move and resize with keyboard */
+ (xevent->xclient.data.l[2] < 9))
+ {
+ Ecore_X_Event_Window_Move_Resize_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->x = xevent->xclient.data.l[0];
+ e->y = xevent->xclient.data.l[1];
+ e->direction = xevent->xclient.data.l[2];
+ e->button = xevent->xclient.data.l[3];
+ e->source = xevent->xclient.data.l[4];
+ ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
+ }
+
+ /* Xdnd Client Message Handling Begin */
+ /* Message Type: XdndEnter target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER)
+ {
+ Ecore_X_Event_Xdnd_Enter *e;
+ Ecore_X_DND_Target *target;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
+ if (!e) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ target = _ecore_x_dnd_target_get();
+ target->state = ECORE_X_DND_TARGET_ENTERED;
+ target->source = xevent->xclient.data.l[0];
+ target->win = xevent->xclient.window;
+ target->version = (int) (xevent->xclient.data.l[1] >> 24);
+ if (target->version > ECORE_X_DND_VERSION)
+ {
+ WRN("DND: Requested version %d, we only support up to %d",
+ target->version, ECORE_X_DND_VERSION);
+ return;
+ }
+
+ if (xevent->xclient.data.l[1] & 0x1UL)
+ {
+ /* source supports more than 3 types, fetch property */
+ unsigned char *data;
+ Ecore_X_Atom *types;
+ int i, num_ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!(ecore_x_window_prop_property_get(target->source,
+ ECORE_X_ATOM_XDND_TYPE_LIST,
+ XA_ATOM,
+ 32, &data, &num_ret)))
+ {
+ WRN("DND: Could not fetch data type list from source window, aborting.");
+ return;
+ }
+ types = (Ecore_X_Atom *)data;
+ e->types = calloc(num_ret, sizeof(char *));
+ if (e->types)
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ for (i = 0; i < num_ret; i++)
+ e->types[i] = XGetAtomName(_ecore_x_disp, types[i]);
+ }
+ e->num_types = num_ret;
+ }
+ else
+ {
+ int i = 0;
+
+ e->types = calloc(3, sizeof(char *));
+ if (e->types)
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ while ((i < 3) && (xevent->xclient.data.l[i + 2]))
+ {
+ e->types[i] = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[i + 2]);
+ i++;
+ }
+ }
+ e->num_types = i;
+ }
+
+ e->win = target->win;
+ e->source = target->source;
+ ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e,
+ _ecore_x_event_free_xdnd_enter, NULL);
+ }
+
+ /* Message Type: XdndPosition target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION)
+ {
+ Ecore_X_Event_Xdnd_Position *e;
+ Ecore_X_DND_Target *target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
+ (target->win != xevent->xclient.window))
+ return;
+
+ target->pos.x = xevent->xclient.data.l[2] >> 16;
+ target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL;
+ target->action = xevent->xclient.data.l[4]; /* Version 2 */
+
+ target->time = (target->version >= 1) ?
+ (Time)xevent->xclient.data.l[3] : CurrentTime;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ e->action = target->action;
+ ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndStatus source */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS)
+ {
+ Ecore_X_Event_Xdnd_Status *e;
+ Ecore_X_DND_Source *source;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ source = _ecore_x_dnd_source_get();
+ /* Make sure source/target match */
+ if ((source->win != xevent->xclient.window ) ||
+ (source->dest != (Window)xevent->xclient.data.l[0]))
+ return;
+
+ source->await_status = 0;
+
+ source->will_accept = xevent->xclient.data.l[1] & 0x1UL;
+ source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1;
+
+ source->rectangle.x = xevent->xclient.data.l[2] >> 16;
+ source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL;
+ source->rectangle.width = xevent->xclient.data.l[3] >> 16;
+ source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL;
+
+ source->accepted_action = xevent->xclient.data.l[4];
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
+ if (!e) return;
+ e->win = source->win;
+ e->target = source->dest;
+ e->will_accept = source->will_accept;
+ e->rectangle.x = source->rectangle.x;
+ e->rectangle.y = source->rectangle.y;
+ e->rectangle.width = source->rectangle.width;
+ e->rectangle.height = source->rectangle.height;
+ e->action = source->accepted_action;
+
+ ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndLeave target */
+ /* Pretend the whole thing never happened, sort of */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE)
+ {
+ Ecore_X_Event_Xdnd_Leave *e;
+ Ecore_X_DND_Target *target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ target = _ecore_x_dnd_target_get();
+ if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
+ (target->win != xevent->xclient.window))
+ return;
+
+ target->state = ECORE_X_DND_TARGET_IDLE;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->source = (Window)xevent->xclient.data.l[0];
+ ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndDrop target */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP)
+ {
+ Ecore_X_Event_Xdnd_Drop *e;
+ Ecore_X_DND_Target *target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ target = _ecore_x_dnd_target_get();
+ /* Match source/target */
+ if ((target->source != (Window)xevent->xclient.data.l[0]) ||
+ (target->win != xevent->xclient.window))
+ return;
+
+ target->time = (target->version >= 1) ?
+ (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
+ if (!e) return;
+ e->win = target->win;
+ e->source = target->source;
+ e->action = target->action;
+ e->position.x = target->pos.x;
+ e->position.y = target->pos.y;
+ ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
+ }
+
+ /* Message Type: XdndFinished source */
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED)
+ {
+ Ecore_X_Event_Xdnd_Finished *e;
+ Ecore_X_DND_Source *source;
+ int completed = 1;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ source = _ecore_x_dnd_source_get();
+ /* Match source/target */
+ if ((source->win != xevent->xclient.window) ||
+ (source->dest != (Window)xevent->xclient.data.l[0]))
+ return;
+
+ if ((source->version < 5) || (xevent->xclient.data.l[1] & 0x1UL))
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* Target successfully performed drop action */
+ ecore_x_selection_xdnd_clear();
+ source->state = ECORE_X_DND_SOURCE_IDLE;
+ }
+ else if (source->version >= 5)
+ {
+ completed = 0;
+ source->state = ECORE_X_DND_SOURCE_CONVERTING;
+
+ /* FIXME: Probably need to add a timer to switch back to idle
+ * and discard the selection data */
+ }
+
+ e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
+ if (!e) return;
+ e->win = source->win;
+ e->target = source->dest;
+ e->completed = completed;
+ if (source->version >= 5)
+ {
+ source->accepted_action = xevent->xclient.data.l[2];
+ e->action = source->accepted_action;
+ }
+ else
+ {
+ source->accepted_action = 0;
+ e->action = source->action;
+ }
+
+ ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
+ }
+ else if (xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_STATE)
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ if (xevent->xclient.data.l[0] == 0)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
+ else if (xevent->xclient.data.l[0] == 1)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ else if (xevent->xclient.data.l[0] == 2)
+ e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
+ else
+ {
+ free(e);
+ return;
+ }
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]);
+ if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+// char *name;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+// name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]);
+// if (name) ERR("Unknown state: %s", name);
+// XFree(name);
+ }
+ e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]);
+ if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
+ {
+// char *name;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+// name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]);
+// if (name) ERR("Unknown state: %s", name);
+// XFree(name);
+ }
+ e->source = xevent->xclient.data.l[3];
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE)
+ && (xevent->xclient.format == 32)
+ && (xevent->xclient.data.l[0] == IconicState))
+ {
+ Ecore_X_Event_Window_State_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
+ e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
+
+ ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
+ && (xevent->xclient.format == 32))
+ {
+ Ecore_X_Event_Desktop_Change *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->desk = xevent->xclient.data.l[0];
+ e->source = xevent->xclient.data.l[1];
+
+ ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
+ {
+ Ecore_X_Event_Frame_Extents_Request *e;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+
+ ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS)
+ && ((Ecore_X_Atom)xevent->xclient.data.l[0] == ECORE_X_ATOM_NET_WM_PING)
+ && (xevent->xclient.format == 32))
+ {
+ Ecore_X_Event_Ping *e;
+ Ecore_X_Window root = 0;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Ping));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->time = xevent->xclient.data.l[1];
+ e->event_win = xevent->xclient.data.l[2];
+
+ /* send a reply anyway - we are alive... eventloop at least */
+ ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
+ if (ScreenCount(_ecore_x_disp) > 1)
+ {
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ root = ecore_x_window_root_get(e->win);
+ }
+ else
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ if (xevent->xclient.window != root)
+ {
+ xevent->xclient.window = root;
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ xevent);
+ }
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
+ (xevent->xclient.format == 8))
+ {
+ _ecore_x_netwm_startup_info_begin(xevent->xclient.window, xevent->xclient.data.b);
+ }
+ else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
+ (xevent->xclient.format == 8))
+ {
+ _ecore_x_netwm_startup_info(xevent->xclient.window, xevent->xclient.data.b);
+ }
+ else if ((xevent->xclient.message_type == 27777)
+ && (xevent->xclient.data.l[0] == 0x7162534)
+ && (xevent->xclient.format == 32)
+ && (xevent->xclient.window == _ecore_x_private_win))
+ {
+ /* a grab sync marker */
+ if (xevent->xclient.data.l[1] == 0x10000001)
+ _ecore_x_window_grab_remove(xevent->xclient.data.l[2]);
+ else if (xevent->xclient.data.l[1] == 0x10000002)
+ _ecore_x_key_grab_remove(xevent->xclient.data.l[2]);
+ }
+ else
+ {
+ Ecore_X_Event_Client_Message *e;
+ int i;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
+ if (!e) return;
+ e->win = xevent->xclient.window;
+ e->message_type = xevent->xclient.message_type;
+ e->format = xevent->xclient.format;
+ for (i = 0; i < 5; i++)
+ e->data.l[i] = xevent->xclient.data.l[i];
+
+ ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
+ }
+}
+
+void
+_ecore_x_event_handle_mapping_notify(XEvent *xevent)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ XRefreshKeyboardMapping((XMappingEvent *)xevent);
+}
+
+void
+_ecore_x_event_handle_shape_change(XEvent *xevent)
+{
+ XShapeEvent *shape_event;
+ Ecore_X_Event_Window_Shape *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ shape_event = (XShapeEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
+ if (!e) return;
+ e->win = shape_event->window;
+ e->time = shape_event->time;
+ ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_screensaver_notify(XEvent *xevent)
+{
+#ifdef ECORE_XSS
+ XScreenSaverNotifyEvent *screensaver_event;
+ Ecore_X_Event_Screensaver_Notify *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ screensaver_event = (XScreenSaverNotifyEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
+ if (!e) return;
+ e->win = screensaver_event->window;
+ if (screensaver_event->state == ScreenSaverOn)
+ e->on = 1;
+ else
+ e->on = 0;
+ e->time = screensaver_event->time;
+ ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
+#else
+ xevent = NULL;
+#endif
+}
+
+void
+_ecore_x_event_handle_sync_counter(XEvent *xevent)
+{
+ XSyncCounterNotifyEvent *sync_counter_event;
+ Ecore_X_Event_Sync_Counter *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ sync_counter_event = (XSyncCounterNotifyEvent *)xevent;
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
+ if (!e) return;
+ e->time = sync_counter_event->time;
+ ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_sync_alarm(XEvent *xevent)
+{
+ XSyncAlarmNotifyEvent *sync_alarm_event;
+ Ecore_X_Event_Sync_Alarm *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ sync_alarm_event = (XSyncAlarmNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
+ if (!e) return;
+ e->time = sync_alarm_event->time;
+ e->alarm = sync_alarm_event->alarm;
+ ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
+}
+
+#ifdef ECORE_XRANDR
+void
+_ecore_x_event_handle_randr_change(XEvent *xevent)
+{
+ XRRScreenChangeNotifyEvent *randr_event;
+ Ecore_X_Event_Screen_Change *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ randr_event = (XRRScreenChangeNotifyEvent *)xevent;
+ if (!XRRUpdateConfiguration(xevent))
+ ERR("Can't update RR config!");
+
+ e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
+ if (!e) return;
+ e->win = randr_event->window;
+ e->root = randr_event->root;
+ e->width = randr_event->width;
+ e->height = randr_event->height;
+ e->time = randr_event->timestamp;
+ e->config_time = randr_event->config_timestamp;
+ e->mm_width = randr_event->mwidth;
+ e->mm_height = randr_event->mheight;
+ e->rotation = randr_event->rotation;
+ e->subpixel_order = randr_event->subpixel_order;
+ ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
+}
+
+static void
+_ecore_x_event_handle_randr_notify_crtc_change(const XRRNotifyEvent *xevent)
+{
+ const XRRCrtcChangeNotifyEvent *randr_event;
+ Ecore_X_Event_Randr_Crtc_Change *e;
+
+ randr_event = (const XRRCrtcChangeNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change));
+ if (!e) return;
+ e->win = randr_event->window;
+ e->crtc = randr_event->crtc;
+ e->mode = randr_event->mode;
+ e->rotation = randr_event->rotation;
+ e->x = randr_event->x;
+ e->y = randr_event->y;
+ e->width = randr_event->width;
+ e->height = randr_event->height;
+ ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL);
+}
+
+static void
+_ecore_x_event_handle_randr_notify_output_change(const XRRNotifyEvent *xevent)
+{
+ const XRROutputChangeNotifyEvent *randr_event;
+ Ecore_X_Event_Randr_Output_Change *e;
+
+ randr_event = (const XRROutputChangeNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change));
+ if (!e) return;
+ e->win = randr_event->window;
+ e->output = randr_event->output;
+ e->crtc = randr_event->crtc;
+ e->mode = randr_event->mode;
+ e->rotation = randr_event->rotation;
+ e->connection = randr_event->connection;
+ e->subpixel_order = randr_event->subpixel_order;
+ ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL);
+}
+
+static void
+_ecore_x_event_handle_randr_notify_output_property(const XRRNotifyEvent *xevent)
+{
+ const XRROutputPropertyNotifyEvent *randr_event;
+ Ecore_X_Event_Randr_Output_Property_Notify *e;
+
+ randr_event = (const XRROutputPropertyNotifyEvent *)xevent;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify));
+ if (!e) return;
+ e->win = randr_event->window;
+ e->output = randr_event->output;
+ e->property = randr_event->property;
+ e->time = randr_event->timestamp;
+ e->state = randr_event->state;
+ ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL);
+}
+
+void
+_ecore_x_event_handle_randr_notify(XEvent *xevent)
+{
+ const XRRNotifyEvent *randr_event;
+
+ _ecore_x_last_event_mouse_move = 0;
+ randr_event = (const XRRNotifyEvent *)xevent;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ switch (randr_event->subtype)
+ {
+ case RRNotify_CrtcChange:
+ _ecore_x_event_handle_randr_notify_crtc_change(randr_event);
+ break;
+ case RRNotify_OutputChange:
+ _ecore_x_event_handle_randr_notify_output_change(randr_event);
+ break;
+ case RRNotify_OutputProperty:
+ _ecore_x_event_handle_randr_notify_output_property(randr_event);
+ break;
+ default:
+ ERR("Unknown XRandR RRNotify subtype: %d.",
+ randr_event->subtype);
+ break;
+ }
+}
+#endif
+
+#ifdef ECORE_XFIXES
+void
+_ecore_x_event_handle_fixes_selection_notify(XEvent *event)
+{
+ _ecore_x_last_event_mouse_move = 0;
+ /* Nothing here yet */
+ event = NULL;
+}
+#endif
+
+#ifdef ECORE_XDAMAGE
+void
+_ecore_x_event_handle_damage_notify(XEvent *event)
+{
+ XDamageNotifyEvent *damage_event;
+ Ecore_X_Event_Damage *e;
+
+ _ecore_x_last_event_mouse_move = 0;
+ damage_event = (XDamageNotifyEvent *)event;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Damage));
+ if (!e) return;
+
+ e->level = damage_event->level;
+ e->drawable = damage_event->drawable;
+ e->damage = damage_event->damage;
+ e->more = damage_event->more;
+ e->time = damage_event->timestamp;
+ e->area.x = damage_event->area.x;
+ e->area.y = damage_event->area.y;
+ e->area.width = damage_event->area.width;
+ e->area.height = damage_event->area.height;
+ e->geometry.x = damage_event->geometry.x;
+ e->geometry.y = damage_event->geometry.y;
+ e->geometry.width = damage_event->geometry.width;
+ e->geometry.height = damage_event->geometry.height;
+
+ ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
+}
+#endif
+
+static void
+_ecore_x_event_free_generic_event(void *data, void *ev)
+{
+#ifdef ECORE_XI2
+ Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic*)ev;
+
+ if (e->data)
+ {
+ XFreeEventData(_ecore_x_disp, (XGenericEventCookie *)data);
+ }
+#endif
+}
+
+void
+_ecore_x_event_handle_generic_event(XEvent *event)
+{
+#ifdef ECORE_XI2
+ XGenericEvent *generic_event;
+ Ecore_X_Event_Generic *e;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ generic_event = (XGenericEvent *)event;
+
+ e = calloc(1, sizeof(Ecore_X_Event_Generic));
+ if (!e) return;
+
+ if (XGetEventData(_ecore_x_disp, &event->xcookie))
+ {
+ e->cookie = event->xcookie.cookie;
+ e->data = event->xcookie.data;
+ }
+ else
+ {
+ e->cookie = 0;
+ e->data = NULL;
+ }
+
+ e->extension = generic_event->extension;
+ e->evtype = generic_event->evtype;
+
+ if (e->extension == _ecore_x_xi2_opcode)
+ {
+ _ecore_x_input_handler(event);
+ }
+
+ ecore_event_add(ECORE_X_EVENT_GENERIC, e, _ecore_x_event_free_generic_event, event);
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+static int _fixes_available;
+#ifdef ECORE_XFIXES
+static int _fixes_major, _fixes_minor;
+#endif
+
+void
+_ecore_x_fixes_init(void)
+{
+#ifdef ECORE_XFIXES
+ _fixes_major = 3;
+ _fixes_minor = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XFixesQueryVersion(_ecore_x_disp, &_fixes_major, &_fixes_minor))
+ _fixes_available = 1;
+ else
+ _fixes_available = 0;
+#else
+ _fixes_available = 0;
+#endif
+}
+
+#ifdef ECORE_XFIXES
+/* I don't know what to call this function. */
+static XRectangle *
+_ecore_x_rectangle_ecore_to_x(Ecore_X_Rectangle *rects, int num)
+{
+ XRectangle *xrect;
+ int i;
+
+ if (num == 0) return NULL;
+
+ xrect = malloc(sizeof(XRectangle) * num);
+ if (!xrect) return NULL;
+ for (i = 0; i < num; i++)
+ {
+ xrect[i].x = rects[i].x;
+ xrect[i].y = rects[i].y;
+ xrect[i].width = rects[i].width;
+ xrect[i].height = rects[i].height;
+ }
+ return xrect;
+}
+
+static Ecore_X_Rectangle *
+_ecore_x_rectangle_x_to_ecore(XRectangle *xrect, int num)
+{
+ Ecore_X_Rectangle *rects;
+ int i;
+
+ if (num == 0) return NULL;
+ rects = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (!rects) return NULL;
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = xrect[i].x;
+ rects[i].y = xrect[i].y;
+ rects[i].width = xrect[i].width;
+ rects[i].height = xrect[i].height;
+ }
+ return rects;
+}
+#endif
+
+EAPI Ecore_X_Region
+ecore_x_region_new(Ecore_X_Rectangle *rects, int num)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+ XRectangle *xrect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xrect = _ecore_x_rectangle_ecore_to_x(rects, num);
+ region = XFixesCreateRegion(_ecore_x_disp, xrect, num);
+ free(xrect);
+ return region;
+#else
+ return 0;
+#endif
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_bitmap(Ecore_X_Pixmap bitmap)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromBitmap(_ecore_x_disp, bitmap);
+ return region;
+#else
+ return 0;
+#endif
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_window(Ecore_X_Window win, Ecore_X_Region_Type type)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromWindow(_ecore_x_disp, win, type);
+ return region;
+#else
+ return 0;
+#endif
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_gc(Ecore_X_GC gc)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromGC(_ecore_x_disp, gc);
+ return region;
+#else
+ return 0;
+#endif
+}
+
+EAPI Ecore_X_Region
+ecore_x_region_new_from_picture(Ecore_X_Picture picture)
+{
+#ifdef ECORE_XFIXES
+ Ecore_X_Region region;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ region = XFixesCreateRegionFromPicture(_ecore_x_disp, picture);
+ return region;
+#else
+ return 0;
+#endif
+}
+
+EAPI void
+ecore_x_region_free(Ecore_X_Region region)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesDestroyRegion(_ecore_x_disp, region);
+#endif
+}
+
+EAPI void
+ecore_x_region_set(Ecore_X_Region region, Ecore_X_Rectangle *rects, int num)
+{
+#ifdef ECORE_XFIXES
+ XRectangle *xrect = _ecore_x_rectangle_ecore_to_x(rects, num);
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetRegion(_ecore_x_disp, region, xrect, num);
+#endif
+}
+
+EAPI void
+ecore_x_region_copy(Ecore_X_Region dest, Ecore_X_Region source)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesCopyRegion(_ecore_x_disp, dest, source);
+#endif
+}
+
+EAPI void
+ecore_x_region_combine(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesUnionRegion(_ecore_x_disp, dest, source1, source2);
+#endif
+}
+
+EAPI void
+ecore_x_region_intersect(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesIntersectRegion(_ecore_x_disp, dest, source1, source2);
+#endif
+}
+
+EAPI void
+ecore_x_region_subtract(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSubtractRegion(_ecore_x_disp, dest, source1, source2);
+#endif
+}
+
+EAPI void
+ecore_x_region_invert(Ecore_X_Region dest, Ecore_X_Rectangle *bounds, Ecore_X_Region source)
+{
+#ifdef ECORE_XFIXES
+ XRectangle *xbound;
+ int num = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ while (bounds + num) num++;
+ xbound = _ecore_x_rectangle_ecore_to_x(bounds, num);
+
+ XFixesInvertRegion(_ecore_x_disp, dest, xbound, source);
+#endif
+}
+
+EAPI void
+ecore_x_region_translate(Ecore_X_Region region, int dx, int dy)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesTranslateRegion(_ecore_x_disp, region, dx, dy);
+#endif
+}
+
+EAPI void
+ecore_x_region_extents(Ecore_X_Region dest, Ecore_X_Region source)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesRegionExtents(_ecore_x_disp, dest, source);
+#endif
+}
+
+EAPI Ecore_X_Rectangle *
+ecore_x_region_fetch(Ecore_X_Region region, int *num, Ecore_X_Rectangle *bounds){
+#ifdef ECORE_XFIXES
+ Ecore_X_Rectangle *rects;
+ XRectangle *xrect, xbound;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xrect = XFixesFetchRegionAndBounds(_ecore_x_disp, region, num, &xbound);
+ rects = _ecore_x_rectangle_x_to_ecore(xrect, *num);
+ (*bounds).x = xbound.x;
+ (*bounds).y = xbound.y;
+ (*bounds).width = xbound.width;
+ (*bounds).height = xbound.height;
+ return rects;
+#else
+ return NULL;
+#endif
+}
+
+EAPI void
+ecore_x_region_expand(Ecore_X_Region dest, Ecore_X_Region source, unsigned int left, unsigned int right, unsigned int top, unsigned int bottom)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesExpandRegion(_ecore_x_disp, dest, source, left, right, top, bottom);
+#endif
+}
+
+EAPI void
+ecore_x_region_gc_clip_set(Ecore_X_Region region, Ecore_X_GC gc, int x_origin, int y_origin)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetGCClipRegion(_ecore_x_disp, gc, x_origin, y_origin, region);
+#endif
+}
+
+EAPI void
+ecore_x_region_window_shape_set(Ecore_X_Region region, Ecore_X_Window win, Ecore_X_Shape_Type type, int x_offset, int y_offset)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetWindowShapeRegion(_ecore_x_disp, win, type, x_offset, y_offset, region);
+#endif
+}
+
+EAPI void
+ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin)
+{
+#ifdef ECORE_XFIXES
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFixesSetPictureClipRegion(_ecore_x_disp, picture, x_origin, y_origin, region);
+#endif
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * Creates a new default graphics context associated with the given
+ * drawable.
+ * @param draw Drawable to create graphics context with. If @c 0 is
+ * given instead, the default root window is used.
+ * @param value_mask Bitmask values.
+ * @param value_list List of values. The order of values must be the
+ * same than the corresponding bitmaks.
+ * @return The new default graphics context.
+ */
+EAPI Ecore_X_GC
+ecore_x_gc_new(Ecore_X_Drawable draw, Ecore_X_GC_Value_Mask value_mask, const unsigned int *value_list)
+{
+ XGCValues gcv;
+ int mask;
+ int index;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!draw) draw = DefaultRootWindow(_ecore_x_disp);
+
+ memset(&gcv, 0, sizeof (gcv));
+
+ for (i = 0, index = 0, mask = 1; i <= 22; i++, mask <<= 1)
+ {
+ switch (mask & value_mask)
+ {
+ case ECORE_X_GC_VALUE_MASK_FUNCTION:
+ gcv.function = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_PLANE_MASK:
+ gcv.plane_mask = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_FOREGROUND:
+ gcv.foreground = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_BACKGROUND:
+ gcv.background = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_LINE_WIDTH:
+ gcv.line_width = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_LINE_STYLE:
+ gcv.line_style = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_CAP_STYLE:
+ gcv.cap_style = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_JOIN_STYLE:
+ gcv.join_style = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_FILL_STYLE:
+ gcv.fill_style = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_FILL_RULE:
+ gcv.fill_rule = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_TILE:
+ gcv.tile = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_STIPPLE:
+ gcv.stipple = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X:
+ gcv.ts_x_origin = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y:
+ gcv.ts_y_origin = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_FONT:
+ gcv.font = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE:
+ gcv.subwindow_mode = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES:
+ gcv.graphics_exposures = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X:
+ gcv.clip_x_origin = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y:
+ gcv.clip_y_origin = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_CLIP_MASK:
+ gcv.clip_mask = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_DASH_OFFSET:
+ gcv.dash_offset = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_DASH_LIST:
+ gcv.dashes = value_list[index];
+ index++;
+ break;
+ case ECORE_X_GC_VALUE_MASK_ARC_MODE:
+ gcv.arc_mode = value_list[index];
+ index++;
+ break;
+ }
+ }
+
+ return XCreateGC(_ecore_x_disp, draw, value_mask, &gcv);
+}
+
+/**
+ * Deletes and frees the given graphics context.
+ * @param gc The given graphics context.
+ */
+EAPI void
+ecore_x_gc_free(Ecore_X_GC gc)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFreeGC(_ecore_x_disp, gc);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * Various ICCCM related functions.
+ *
+ * This is ALL the code involving anything ICCCM related. for both WM and
+ * client.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+
+EAPI void
+ecore_x_icccm_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+}
+
+EAPI void
+ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state)
+{
+ unsigned long c[2];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ c[0] = WithdrawnState;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ c[0] = NormalState;
+ else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ c[0] = IconicState;
+ c[1] = None;
+ XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
+ ECORE_X_ATOM_WM_STATE, 32, PropModeReplace,
+ (unsigned char *)c, 2);
+}
+
+EAPI Ecore_X_Window_State_Hint
+ecore_x_icccm_state_get(Ecore_X_Window win)
+{
+ unsigned char *prop_ret = NULL;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ Ecore_X_Window_State_Hint hint;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ hint = ECORE_X_WINDOW_STATE_HINT_NONE;
+ XGetWindowProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
+ 0, 0x7fffffff, False, ECORE_X_ATOM_WM_STATE,
+ &type_ret, &format_ret, &num_ret, &bytes_after,
+ &prop_ret);
+ if ((prop_ret) && (num_ret == 2))
+ {
+ if (prop_ret[0] == WithdrawnState)
+ hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (prop_ret[0] == NormalState)
+ hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (prop_ret[0] == IconicState)
+ hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return hint;
+}
+
+EAPI void
+ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_DELETE_WINDOW,
+ t, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_TAKE_FOCUS,
+ t, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
+ ECORE_X_EVENT_MASK_NONE,
+ ECORE_X_ATOM_WM_SAVE_YOURSELF,
+ t, 0, 0, 0);
+}
+
+EAPI void
+ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XEvent ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ev.type = ConfigureNotify;
+ ev.xconfigure.display = _ecore_x_disp;
+ ev.xconfigure.event = win;
+ ev.xconfigure.window = win;
+ ev.xconfigure.x = x;
+ ev.xconfigure.y = y;
+ ev.xconfigure.width = w;
+ ev.xconfigure.height = h;
+ ev.xconfigure.border_width = 0;
+ ev.xconfigure.above = None;
+ ev.xconfigure.override_redirect = False;
+ XSendEvent(_ecore_x_disp, win, False, StructureNotifyMask, &ev);
+}
+
+EAPI void
+ecore_x_icccm_hints_set(Ecore_X_Window win,
+ int accepts_focus,
+ Ecore_X_Window_State_Hint initial_state,
+ Ecore_X_Pixmap icon_pixmap,
+ Ecore_X_Pixmap icon_mask,
+ Ecore_X_Window icon_window,
+ Ecore_X_Window window_group, int is_urgent)
+{
+ XWMHints *hints;
+
+ hints = XAllocWMHints();
+ if (!hints)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ hints->flags = InputHint | StateHint;
+ hints->input = accepts_focus;
+ if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ hints->initial_state = WithdrawnState;
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
+ hints->initial_state = NormalState;
+ else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
+ hints->initial_state = IconicState;
+ if (icon_pixmap != 0)
+ {
+ hints->icon_pixmap = icon_pixmap;
+ hints->flags |= IconPixmapHint;
+ }
+ if (icon_mask != 0)
+ {
+ hints->icon_mask = icon_mask;
+ hints->flags |= IconMaskHint;
+ }
+ if (icon_window != 0)
+ {
+ hints->icon_window = icon_window;
+ hints->flags |= IconWindowHint;
+ }
+ if (window_group != 0)
+ {
+ hints->window_group = window_group;
+ hints->flags |= WindowGroupHint;
+ }
+ if (is_urgent)
+ hints->flags |= XUrgencyHint;
+ XSetWMHints(_ecore_x_disp, win, hints);
+ XFree(hints);
+}
+
+EAPI int
+ecore_x_icccm_hints_get(Ecore_X_Window win,
+ int *accepts_focus,
+ Ecore_X_Window_State_Hint *initial_state,
+ Ecore_X_Pixmap *icon_pixmap,
+ Ecore_X_Pixmap *icon_mask,
+ Ecore_X_Window *icon_window,
+ Ecore_X_Window *window_group, int *is_urgent)
+{
+ XWMHints *hints;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (accepts_focus)
+ *accepts_focus = 1;
+ if (initial_state)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ if (icon_pixmap)
+ *icon_pixmap = 0;
+ if (icon_mask)
+ *icon_mask = 0;
+ if (icon_window)
+ *icon_window = 0;
+ if (window_group)
+ *window_group = 0;
+ if (is_urgent)
+ *is_urgent = 0;
+ hints = XGetWMHints(_ecore_x_disp, win);
+ if (hints)
+ {
+ if ((hints->flags & InputHint) && (accepts_focus))
+ {
+ if (hints->input)
+ *accepts_focus = 1;
+ else
+ *accepts_focus = 0;
+ }
+ if ((hints->flags & StateHint) && (initial_state))
+ {
+ if (hints->initial_state == WithdrawnState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
+ else if (hints->initial_state == NormalState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+ else if (hints->initial_state == IconicState)
+ *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+ }
+ if ((hints->flags & IconPixmapHint) && (icon_pixmap))
+ {
+ *icon_pixmap = hints->icon_pixmap;
+ }
+ if ((hints->flags & IconMaskHint) && (icon_mask))
+ {
+ *icon_mask = hints->icon_mask;
+ }
+ if ((hints->flags & IconWindowHint) && (icon_window))
+ {
+ *icon_window = hints->icon_window;
+ }
+ if ((hints->flags & WindowGroupHint) && (window_group))
+ {
+ *window_group = hints->window_group;
+ }
+ if ((hints->flags & XUrgencyHint) && (is_urgent))
+ {
+ *is_urgent = 1;
+ }
+ XFree(hints);
+ return 1;
+ }
+ return 0;
+}
+
+EAPI void
+ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
+ int request_pos,
+ Ecore_X_Gravity gravity,
+ int min_w, int min_h,
+ int max_w, int max_h,
+ int base_w, int base_h,
+ int step_x, int step_y,
+ double min_aspect, double max_aspect)
+{
+ XSizeHints hint;
+ long mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
+ {
+ memset(&hint, 0, sizeof(XSizeHints));
+ }
+
+ hint.flags = 0;
+ if (request_pos)
+ {
+ hint.flags |= USPosition;
+ }
+ if (gravity != ECORE_X_GRAVITY_NW)
+ {
+ hint.flags |= PWinGravity;
+ hint.win_gravity = gravity;
+ }
+ if ((min_w > 0) || (min_h > 0))
+ {
+ hint.flags |= PMinSize;
+ hint.min_width = min_w;
+ hint.min_height = min_h;
+ }
+ if ((max_w > 0) || (max_h > 0))
+ {
+ hint.flags |= PMaxSize;
+ hint.max_width = max_w;
+ hint.max_height = max_h;
+ }
+ if ((base_w > 0) || (base_h > 0))
+ {
+ hint.flags |= PBaseSize;
+ hint.base_width = base_w;
+ hint.base_height = base_h;
+ }
+ if ((step_x > 1) || (step_y > 1))
+ {
+ hint.flags |= PResizeInc;
+ hint.width_inc = step_x;
+ hint.height_inc = step_y;
+ }
+ if ((min_aspect > 0.0) || (max_aspect > 0.0))
+ {
+ hint.flags |= PAspect;
+ hint.min_aspect.x = min_aspect * 10000;
+ hint.min_aspect.y = 10000;
+ hint.max_aspect.x = max_aspect * 10000;
+ hint.max_aspect.y = 10000;
+ }
+ XSetWMNormalHints(_ecore_x_disp, win, &hint);
+}
+
+EAPI int
+ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
+ int *request_pos,
+ Ecore_X_Gravity *gravity,
+ int *min_w, int *min_h,
+ int *max_w, int *max_h,
+ int *base_w, int *base_h,
+ int *step_x, int *step_y,
+ double *min_aspect, double *max_aspect)
+{
+ XSizeHints hint;
+ long mask;
+
+ int minw = 0, minh = 0;
+ int maxw = 32767, maxh = 32767;
+ int basew = -1, baseh = -1;
+ int stepx = -1, stepy = -1;
+ double mina = 0.0, maxa = 0.0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask))
+ return 0;
+
+ if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
+ {
+ if (request_pos)
+ *request_pos = 1;
+ }
+ else
+ {
+ if (request_pos)
+ *request_pos = 0;
+ }
+ if (hint.flags & PWinGravity)
+ {
+ if (gravity)
+ *gravity = hint.win_gravity;
+ }
+ else
+ {
+ if (gravity)
+ *gravity = ECORE_X_GRAVITY_NW;
+ }
+ if (hint.flags & PMinSize)
+ {
+ minw = hint.min_width;
+ minh = hint.min_height;
+ }
+ if (hint.flags & PMaxSize)
+ {
+ maxw = hint.max_width;
+ maxh = hint.max_height;
+ if (maxw < minw)
+ maxw = minw;
+ if (maxh < minh)
+ maxh = minh;
+ }
+ if (hint.flags & PBaseSize)
+ {
+ basew = hint.base_width;
+ baseh = hint.base_height;
+ if (basew > minw)
+ minw = basew;
+ if (baseh > minh)
+ minh = baseh;
+ }
+ if (hint.flags & PResizeInc)
+ {
+ stepx = hint.width_inc;
+ stepy = hint.height_inc;
+ if (stepx < 1)
+ stepx = 1;
+ if (stepy < 1)
+ stepy = 1;
+ }
+ if (hint.flags & PAspect)
+ {
+ if (hint.min_aspect.y > 0)
+ mina = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y);
+ if (hint.max_aspect.y > 0)
+ maxa = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y);
+ }
+ if (min_w)
+ *min_w = minw;
+ if (min_h)
+ *min_h = minh;
+ if (max_w)
+ *max_w = maxw;
+ if (max_h)
+ *max_h = maxh;
+ if (base_w)
+ *base_w = basew;
+ if (base_h)
+ *base_h = baseh;
+ if (step_x)
+ *step_x = stepx;
+ if (step_y)
+ *step_y = stepy;
+ if (min_aspect)
+ *min_aspect = mina;
+ if (max_aspect)
+ *max_aspect = maxa;
+ return 1;
+}
+
+EAPI void
+ecore_x_icccm_title_set(Ecore_X_Window win, const char *t)
+{
+ char *list[1];
+ XTextProperty xprop;
+ int ret;
+
+ if (!t) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+#ifdef X_HAVE_UTF8_STRING
+ list[0] = strdup(t);
+ ret =
+ Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, XUTF8StringStyle,
+ &xprop);
+#else
+ list[0] = strdup(t);
+ ret =
+ XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle,
+ &xprop);
+#endif
+ if (ret >= Success)
+ {
+ XSetWMName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ else
+ {
+ if (XStringListToTextProperty(list, 1, &xprop) >= Success)
+ {
+ XSetWMName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ }
+ free(list[0]);
+}
+
+EAPI char *
+ecore_x_icccm_title_get(Ecore_X_Window win)
+{
+ XTextProperty xprop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+ if (XGetWMName(_ecore_x_disp, win, &xprop) >= Success)
+ {
+ if (xprop.value)
+ {
+ char **list = NULL;
+ char *t = NULL;
+ int num = 0;
+ int ret;
+
+ if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else
+ {
+
+ /* convert to utf8 */
+#ifdef X_HAVE_UTF8_STRING
+ ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#else
+ ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#endif
+
+ if ((ret == XLocaleNotSupported) ||
+ (ret == XNoMemory) || (ret == XConverterNotFound))
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else if ((ret >= Success) && (num > 0))
+ {
+ t = strdup(list[0]);
+ }
+ if (list)
+ XFreeStringList(list);
+ }
+
+ if (xprop.value) XFree(xprop.value);
+ return t;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Set protocol atoms explicitly
+ * @param win The Window
+ * @param protos An array of protocol atoms
+ * @param num the number of members of the array
+ */
+EAPI void
+ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win, Ecore_X_Atom *protos, int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num > 0)
+ XSetWMProtocols(_ecore_x_disp, win, (Atom *)(protos), num);
+ else
+ XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_PROTOCOLS);
+}
+
+/**
+ * Set or unset a wm protocol property.
+ * @param win The Window
+ * @param protocol The protocol to enable/disable
+ * @param on On/Off
+ */
+EAPI void
+ecore_x_icccm_protocol_set(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol, int on)
+{
+ Atom *protos = NULL;
+ Atom proto;
+ int protos_count = 0;
+ int already_set = 0;
+ int i;
+
+ /* Check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ {
+ protos = NULL;
+ protos_count = 0;
+ }
+
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ already_set = 1;
+ break;
+ }
+ }
+
+ if (on)
+ {
+ Atom *new_protos = NULL;
+
+ if (already_set)
+ goto leave;
+ new_protos = malloc((protos_count + 1) * sizeof(Atom));
+ if (!new_protos)
+ goto leave;
+ for (i = 0; i < protos_count; i++)
+ new_protos[i] = protos[i];
+ new_protos[protos_count] = proto;
+ XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1);
+ free(new_protos);
+ }
+ else
+ {
+ if (!already_set)
+ goto leave;
+ for (i = 0; i < protos_count; i++)
+ {
+ if (protos[i] == proto)
+ {
+ int j;
+
+ for (j = i + 1; j < protos_count; j++)
+ protos[j - 1] = protos[j];
+ if (protos_count > 1)
+ XSetWMProtocols(_ecore_x_disp, win, protos,
+ protos_count - 1);
+ else
+ XDeleteProperty(_ecore_x_disp, win,
+ ECORE_X_ATOM_WM_PROTOCOLS);
+ goto leave;
+ }
+ }
+ }
+
+ leave:
+ if (protos)
+ XFree(protos);
+
+}
+
+/**
+ * Determines whether a protocol is set for a window.
+ * @param win The Window
+ * @param protocol The protocol to query
+ * @return 1 if the protocol is set, else 0.
+ */
+EAPI int
+ecore_x_icccm_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol)
+{
+ Atom proto, *protos = NULL;
+ int i, ret = 0, protos_count = 0;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return 0;
+
+ for (i = 0; i < protos_count; i++)
+ if (protos[i] == proto)
+ {
+ ret = 1;
+ break;
+ }
+
+ if (protos) XFree(protos);
+ return ret;
+
+}
+
+/**
+ * Set a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Set a window name * class
+ */
+EAPI void
+ecore_x_icccm_name_class_set(Ecore_X_Window win, const char *n, const char *c)
+{
+ XClassHint *xch;
+
+ xch = XAllocClassHint();
+ if (!xch)
+ return;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xch->res_name = (char *)n;
+ xch->res_class = (char *)c;
+ XSetClassHint(_ecore_x_disp, win, xch);
+ XFree(xch);
+}
+
+/**
+ * Get a window name & class.
+ * @param win The window
+ * @param n The name string
+ * @param c The class string
+ *
+ * Get a window name * class
+ */
+EAPI void
+ecore_x_icccm_name_class_get(Ecore_X_Window win, char **n, char **c)
+{
+ XClassHint xch;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (n) *n = NULL;
+ if (c) *c = NULL;
+ xch.res_name = NULL;
+ xch.res_class = NULL;
+ if (XGetClassHint(_ecore_x_disp, win, &xch))
+ {
+ if (n)
+ {
+ if (xch.res_name) *n = strdup(xch.res_name);
+ }
+ if (c)
+ {
+ if (xch.res_class) *c = strdup(xch.res_class);
+ }
+ XFree(xch.res_name);
+ XFree(xch.res_class);
+ }
+}
+
+/**
+ * Get a window client machine string.
+ * @param win The window
+ * @return The windows client machine string
+ *
+ * Return the client machine of a window. String must be free'd when done with.
+ */
+EAPI char *
+ecore_x_icccm_client_machine_get(Ecore_X_Window win)
+{
+ char *name;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ name = ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_CLIENT_MACHINE);
+ return name;
+}
+
+/**
+ * Sets the WM_COMMAND property for @a win.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+EAPI void
+ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetCommand(_ecore_x_disp, win, argv, argc);
+}
+
+/**
+ * Get the WM_COMMAND property for @a win.
+ *
+ * Return the command of a window. String must be free'd when done with.
+ *
+ * @param win The window.
+ * @param argc Number of arguments.
+ * @param argv Arguments.
+ */
+EAPI void
+ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv)
+{
+ int i, c;
+ char **v;
+
+ if (argc) *argc = 0;
+ if (argv) *argv = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetCommand(_ecore_x_disp, win, &v, &c))
+ return;
+ if (c < 1)
+ {
+ if (v)
+ XFreeStringList(v);
+ return;
+ }
+
+ if (argc) *argc = c;
+ if (argv)
+ {
+ (*argv) = malloc(c * sizeof(char *));
+ if (!*argv)
+ {
+ XFreeStringList(v);
+ if (argc) *argc = 0;
+ return;
+ }
+ for (i = 0; i < c; i++)
+ {
+ if (v[i])
+ (*argv)[i] = strdup(v[i]);
+ else
+ (*argv)[i] = strdup("");
+ }
+ }
+ XFreeStringList(v);
+}
+
+/**
+ * Set a window icon name.
+ * @param win The window
+ * @param t The icon name string
+ *
+ * Set a window icon name
+ */
+EAPI void
+ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *t)
+{
+ char *list[1];
+ XTextProperty xprop;
+ int ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+#ifdef X_HAVE_UTF8_STRING
+ list[0] = strdup(t);
+ ret = Xutf8TextListToTextProperty(_ecore_x_disp, list, 1,
+ XUTF8StringStyle, &xprop);
+#else
+ list[0] = strdup(t);
+ ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1,
+ XStdICCTextStyle, &xprop);
+#endif
+ if (ret >= Success)
+ {
+ XSetWMIconName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ else
+ {
+ if (XStringListToTextProperty(list, 1, &xprop) >= Success)
+ {
+ XSetWMIconName(_ecore_x_disp, win, &xprop);
+ if (xprop.value) XFree(xprop.value);
+ }
+ }
+ free(list[0]);
+}
+
+/**
+ * Get a window icon name.
+ * @param win The window
+ * @return The windows icon name string
+ *
+ * Return the icon name of a window. String must be free'd when done with.
+ */
+EAPI char *
+ecore_x_icccm_icon_name_get(Ecore_X_Window win)
+{
+ XTextProperty xprop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xprop.value = NULL;
+ if (XGetWMIconName(_ecore_x_disp, win, &xprop) >= Success)
+ {
+ if (xprop.value)
+ {
+ char **list = NULL;
+ char *t = NULL;
+ int num = 0;
+ int ret;
+
+ if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING)
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else
+ {
+
+ /* convert to utf8 */
+#ifdef X_HAVE_UTF8_STRING
+ ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#else
+ ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
+ &list, &num);
+#endif
+
+ if ((ret == XLocaleNotSupported) ||
+ (ret == XNoMemory) || (ret == XConverterNotFound))
+ {
+ t = strdup((char *)xprop.value);
+ }
+ else if (ret >= Success)
+ {
+ if ((num >= 1) && (list))
+ {
+ t = strdup(list[0]);
+ }
+ if (list)
+ XFreeStringList(list);
+ }
+ }
+
+ if (xprop.value) XFree(xprop.value);
+ return t;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Add a subwindow to the list of windows that need a different colormap installed.
+ * @param win The toplevel window
+ * @param subwin The subwindow to be added to the colormap windows list
+ */
+EAPI void
+ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin)
+{
+ int num = 0, i;
+ unsigned char *old_data = NULL;
+ unsigned char *data = NULL;
+ Window *oldset = NULL;
+ Window *newset = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, &old_data, &num))
+ {
+ newset = calloc(1, sizeof(Window));
+ if (!newset)
+ return;
+ newset[0] = subwin;
+ num = 1;
+ data = (unsigned char *)newset;
+ }
+ else
+ {
+ newset = calloc(num + 1, sizeof(Window));
+ oldset = (Window *) old_data;
+ if (!newset)
+ return;
+ for (i = 0; i < num; ++i)
+ {
+ if (oldset[i] == subwin)
+ {
+ if (old_data) XFree(old_data);
+ old_data = NULL;
+ free(newset);
+ return;
+ }
+
+ newset[i] = oldset[i];
+ }
+
+ newset[num++] = subwin;
+ if (old_data) XFree(old_data);
+ data = (unsigned char *)newset;
+ }
+
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, data, num);
+ free(newset);
+}
+
+/**
+ * Remove a window from the list of colormap windows.
+ * @param win The toplevel window
+ * @param subwin The window to be removed from the colormap window list.
+ */
+EAPI void
+ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin)
+{
+ int num = 0, i, j, k = 0;
+ unsigned char *old_data = NULL;
+ unsigned char *data = NULL;
+ Window *oldset = NULL;
+ Window *newset = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, &old_data, &num))
+ return;
+
+ oldset = (Window *) old_data;
+ for (i = 0; i < num; i++)
+ {
+ if (oldset[i] == subwin)
+ {
+ if (num == 1)
+ {
+ XDeleteProperty(_ecore_x_disp,
+ win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
+ if (old_data) XFree(old_data);
+ old_data = NULL;
+ return;
+ }
+ else
+ {
+ newset = calloc(num - 1, sizeof(Window));
+ data = (unsigned char *)newset;
+ for (j = 0; j < num; ++j)
+ if (oldset[j] != subwin)
+ newset[k++] = oldset[j];
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
+ XA_WINDOW, 32, data, k);
+ if (old_data) XFree(old_data);
+ old_data = NULL;
+ free(newset);
+ return;
+ }
+ }
+ }
+
+ if (old_data) XFree(old_data);
+}
+
+/**
+ * Specify that a window is transient for another top-level window and should be handled accordingly.
+ * @param win the transient window
+ * @param forwin the toplevel window
+ */
+EAPI void
+ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwin)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetTransientForHint(_ecore_x_disp, win, forwin);
+}
+
+/**
+ * Remove the transient_for setting from a window.
+ * @param The window
+ */
+EAPI void
+ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
+}
+
+/**
+ * Get the window this window is transient for, if any.
+ * @param win The window to check
+ * @return The window ID of the top-level window, or 0 if the property does not exist.
+ */
+EAPI Ecore_X_Window
+ecore_x_icccm_transient_for_get(Ecore_X_Window win)
+{
+ Window forwin;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XGetTransientForHint(_ecore_x_disp, win, &forwin))
+ return (Ecore_X_Window) forwin;
+ else
+ return 0;
+
+}
+
+/**
+ * Set the window role hint.
+ * @param win The window
+ * @param role The role string
+ */
+EAPI void
+ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE,
+ (char *)role);
+}
+
+/**
+ * Get the window role.
+ * @param win The window
+ * @return The window's role string.
+ */
+EAPI char *
+ecore_x_icccm_window_role_get(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
+}
+
+/**
+ * Set the window's client leader.
+ * @param win The window
+ * @param l The client leader window
+ *
+ * All non-transient top-level windows created by an app other than
+ * the main window must have this property set to the app's main window.
+ */
+EAPI void
+ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window l)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
+ &l, 1);
+}
+
+/**
+ * Get the window's client leader.
+ * @param win The window
+ * @return The window's client leader window, or 0 if unset */
+EAPI Ecore_X_Window
+ecore_x_icccm_client_leader_get(Ecore_X_Window win)
+{
+ Ecore_X_Window l;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
+ &l, 1) > 0)
+ return l;
+ return 0;
+}
+
+EAPI void
+ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root)
+{
+ XEvent xev;
+
+ if (!win) return;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_CHANGE_STATE;
+ xev.xclient.data.l[0] = IconicState;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+/* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */
+/* hints. each should go in their own file/section so we know which */
+/* is which. also older kde hints too. we should try support as much */
+/* as makese sense to support */
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+#include <X11/extensions/XShm.h>
+#include <X11/Xutil.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <string.h>
+
+static int _ecore_x_image_shm_can = -1;
+static int _ecore_x_image_err = 0;
+
+static void
+_ecore_x_image_error_handler(Display * d __UNUSED__, XErrorEvent * ev __UNUSED__)
+{
+ _ecore_x_image_err = 1;
+}
+
+static void
+_ecore_x_image_shm_check(void)
+{
+ XErrorHandler ph;
+ XShmSegmentInfo shminfo;
+ XImage *xim;
+
+ if (_ecore_x_image_shm_can != -1) return;
+
+ XSync(_ecore_x_disp, False);
+ _ecore_x_image_err = 0;
+
+ xim = XShmCreateImage(_ecore_x_disp,
+ DefaultVisual(_ecore_x_disp,
+ DefaultScreen(_ecore_x_disp)),
+ DefaultDepth(_ecore_x_disp,
+ DefaultScreen(_ecore_x_disp)),
+ ZPixmap, NULL,
+ &shminfo, 1, 1);
+ if (!xim)
+ {
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
+ IPC_CREAT | 0666);
+ if (shminfo.shmid == -1)
+ {
+ XDestroyImage(xim);
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ shminfo.readOnly = False;
+ shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
+ xim->data = shminfo.shmaddr;
+
+ if (xim->data == (char *)-1)
+ {
+ XDestroyImage(xim);
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
+ XShmAttach(_ecore_x_disp, &shminfo);
+ XShmGetImage(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp),
+ xim, 0, 0, 0xffffffff);
+ XSync(_ecore_x_disp, False);
+ XSetErrorHandler((XErrorHandler)ph);
+ if (_ecore_x_image_err)
+ {
+ XShmDetach(_ecore_x_disp, &shminfo);
+ XDestroyImage(xim);
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+ _ecore_x_image_shm_can = 0;
+ return;
+ }
+
+ XShmDetach(_ecore_x_disp, &shminfo);
+ XDestroyImage(xim);
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+
+ _ecore_x_image_shm_can = 1;
+}
+
+struct _Ecore_X_Image
+{
+ XShmSegmentInfo shminfo;
+ Ecore_X_Visual vis;
+ XImage *xim;
+ int depth;
+ int w, h;
+ int bpl, bpp, rows;
+ unsigned char *data;
+ Eina_Bool shm : 1;
+};
+
+EAPI Ecore_X_Image *
+ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth)
+{
+ Ecore_X_Image *im;
+
+ im = calloc(1, sizeof(Ecore_X_Image));
+ if (!im) return NULL;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ im->w = w;
+ im->h = h;
+ im->vis = vis;
+ im->depth = depth;
+ _ecore_x_image_shm_check();
+ im->shm = _ecore_x_image_shm_can;
+ return im;
+}
+
+EAPI void
+ecore_x_image_free(Ecore_X_Image *im)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (im->shm)
+ {
+ if (im->xim)
+ {
+ XShmDetach(_ecore_x_disp, &(im->shminfo));
+ XDestroyImage(im->xim);
+ shmdt(im->shminfo.shmaddr);
+ shmctl(im->shminfo.shmid, IPC_RMID, 0);
+ }
+ }
+ else
+ {
+ if (im->xim)
+ {
+ free(im->xim->data);
+ im->xim->data = NULL;
+ XDestroyImage(im->xim);
+ }
+ }
+ free(im);
+}
+
+static void
+_ecore_x_image_shm_create(Ecore_X_Image *im)
+{
+ im->xim = XShmCreateImage(_ecore_x_disp, im->vis, im->depth,
+ ZPixmap, NULL, &(im->shminfo),
+ im->w, im->h);
+ if (!im->xim) return;
+
+ im->shminfo.shmid = shmget(IPC_PRIVATE,
+ im->xim->bytes_per_line * im->xim->height,
+ IPC_CREAT | 0666);
+ if (im->shminfo.shmid == -1)
+ {
+ XDestroyImage(im->xim);
+ return;
+ }
+ im->shminfo.readOnly = False;
+ im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
+ im->xim->data = im->shminfo.shmaddr;
+ if ((im->xim->data == (char *)-1) ||
+ (im->xim->data == NULL))
+ {
+ shmdt(im->shminfo.shmaddr);
+ shmctl(im->shminfo.shmid, IPC_RMID, 0);
+ XDestroyImage(im->xim);
+ return;
+ }
+ XShmAttach(_ecore_x_disp, &im->shminfo);
+
+ im->data = (unsigned char *)im->xim->data;
+
+ im->bpl = im->xim->bytes_per_line;
+ im->rows = im->xim->height;
+ if (im->xim->bits_per_pixel <= 8) im->bpp = 1;
+ else if (im->xim->bits_per_pixel <= 16) im->bpp = 2;
+ else im->bpp = 4;
+}
+
+EAPI Eina_Bool
+ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw,
+ int x, int y, int sx, int sy, int w, int h)
+{
+ int ret = 1;
+ XErrorHandler ph;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (im->shm)
+ {
+ if (!im->xim) _ecore_x_image_shm_create(im);
+ if (!im->xim) return 0;
+ _ecore_x_image_err = 0;
+ // optimised path
+ ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
+ if ((sx == 0) && (w == im->w))
+ {
+ im->xim->data = (char *)
+ im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
+ im->xim->width = w;
+ im->xim->height = h;
+ if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
+ ret = 0;
+ ecore_x_sync();
+ }
+ // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
+ else
+ {
+ Ecore_X_Image *tim;
+ unsigned char *spixels, *sp, *pixels, *p;
+ int bpp, bpl, rows, sbpp, sbpl, srows;
+ int r;
+
+ tim = ecore_x_image_new(w, h, im->vis, im->depth);
+ if (tim)
+ {
+ ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
+ if (ret)
+ {
+ spixels = ecore_x_image_data_get(tim, &sbpl, &srows, &sbpp);
+ pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
+ if ((pixels) && (spixels))
+ {
+ p = pixels + (sy * bpl) + (sx * bpp);
+ sp = spixels;
+ for (r = srows; r > 0; r--)
+ {
+ memcpy(p, sp, sbpl);
+ p += bpl;
+ sp += sbpl;
+ }
+ }
+ }
+ ecore_x_image_free(tim);
+ }
+ }
+ XSetErrorHandler((XErrorHandler)ph);
+ if (_ecore_x_image_err) ret = 0;
+ }
+ else
+ {
+ printf("currently unimplemented ecore_x_image_get without shm\n");
+ ret = 0;
+ }
+ return ret;
+}
+
+EAPI void
+ecore_x_image_put(Ecore_X_Image *im __UNUSED__, Ecore_X_Drawable draw __UNUSED__, int x __UNUSED__, int y __UNUSED__, int sx __UNUSED__, int sy __UNUSED__, int w __UNUSED__, int h __UNUSED__)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ printf("ecore_x_image_put: unimplemented!\n");
+}
+
+EAPI void *
+ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!im->xim) _ecore_x_image_shm_create(im);
+ if (!im->xim) return NULL;
+
+ if (bpl) *bpl = im->bpl;
+ if (rows) *rows = im->rows;
+ if (bpp) *bpp = im->bpp;
+ return im->data;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * Various MWM related functions.
+ *
+ * This is ALL the code involving anything MWM related. for both WM and
+ * client.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#define ECORE_X_MWM_HINTS_FUNCTIONS (1 << 0)
+#define ECORE_X_MWM_HINTS_DECORATIONS (1 << 1)
+#define ECORE_X_MWM_HINTS_INPUT_MODE (1 << 2)
+#define ECORE_X_MWM_HINTS_STATUS (1 << 3)
+
+typedef struct _mwmhints
+{
+ CARD32 flags;
+ CARD32 functions;
+ CARD32 decorations;
+ INT32 inputmode;
+ CARD32 status;
+}
+MWMHints;
+
+EAPI int
+ecore_x_mwm_hints_get(Ecore_X_Window win,
+ Ecore_X_MWM_Hint_Func * fhint,
+ Ecore_X_MWM_Hint_Decor * dhint,
+ Ecore_X_MWM_Hint_Input * ihint)
+{
+ unsigned char *p = NULL;
+ MWMHints *mwmhints = NULL;
+ int num;
+ int ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = 0;
+ if (!ecore_x_window_prop_property_get(win,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 32, &p, &num))
+ return 0;
+ mwmhints = (MWMHints *) p;
+ if (mwmhints)
+ {
+ if (num >= 4)
+ {
+ if (dhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_DECORATIONS)
+ *dhint = mwmhints->decorations;
+ else
+ *dhint = ECORE_X_MWM_HINT_DECOR_ALL;
+ }
+ if (fhint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_FUNCTIONS)
+ *fhint = mwmhints->functions;
+ else
+ *fhint = ECORE_X_MWM_HINT_FUNC_ALL;
+ }
+ if (ihint)
+ {
+ if (mwmhints->flags & ECORE_X_MWM_HINTS_INPUT_MODE)
+ *ihint = mwmhints->inputmode;
+ else
+ *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS;
+ }
+ ret = 1;
+ }
+ free(mwmhints);
+ }
+ return ret;
+}
+
+EAPI void
+ecore_x_mwm_borderless_set(Ecore_X_Window win, int borderless)
+{
+ unsigned int data[5] = {0, 0, 0, 0, 0};
+
+ data[0] = 2; /* just set the decorations hint! */
+ data[2] = !borderless;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_property_set(win,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ ECORE_X_ATOM_MOTIF_WM_HINTS,
+ 32, (void *)data, 5);
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
+
+struct _Ecore_X_Startup_Info
+{
+ Ecore_X_Window win;
+
+ int init;
+
+ int buffer_size;
+ char *buffer;
+
+ int length;
+
+ /* These are the sequence info fields */
+ char *id;
+ char *name;
+ int screen;
+ char *bin;
+ char *icon;
+ int desktop;
+ int timestamp;
+ char *description;
+ char *wmclass;
+ int silent;
+};
+
+static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win, Ecore_X_Atom atom, const char *str);
+static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win, Ecore_X_Atom atom);
+#if 0 /* Unused */
+static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info);
+static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, char *data);
+#endif
+static void _ecore_x_netwm_startup_info_free(void *data);
+
+/*
+ * Convenience macros
+ */
+#define _ATOM_SET_UTF8_STRING_LIST(win, atom, string, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8, PropModeReplace, \
+ (unsigned char *)string, cnt)
+
+/*
+ * Local variables
+ */
+
+static Eina_Hash *startup_info = NULL;
+
+EAPI void
+ecore_x_netwm_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ startup_info = eina_hash_string_superfast_new(_ecore_x_netwm_startup_info_free);
+}
+
+EAPI void
+ecore_x_netwm_shutdown(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (startup_info)
+ eina_hash_free(startup_info);
+ startup_info = NULL;
+}
+
+/*
+ * WM identification
+ */
+EAPI void
+ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check,
+ const char *wm_name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
+ ecore_x_window_prop_window_set(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
+ _ecore_x_window_prop_string_utf8_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name);
+ /* This one isn't mandatory */
+ _ecore_x_window_prop_string_utf8_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name);
+}
+
+/*
+ * Set supported atoms
+ */
+EAPI void
+ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_atom_set(root, ECORE_X_ATOM_NET_SUPPORTED, supported, num);
+}
+
+EAPI int
+ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num)
+{
+ int num_ret;
+
+ if (num) *num = 0;
+ if (supported) *supported = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ num_ret = ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED,
+ supported);
+ if (num_ret <= 0)
+ return 0;
+
+ if (num) *num = num_ret;
+ return 1;
+}
+
+/*
+ * Desktop configuration and status
+ */
+EAPI void
+ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
+ &n_desks, 1);
+}
+
+EAPI void
+ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
+ Ecore_X_Window *vroots, unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, vroots, n_desks);
+}
+
+EAPI void
+ecore_x_netwm_desk_names_set(Ecore_X_Window root,
+ const char **names, unsigned int n_desks)
+{
+ char ss[32], *buf;
+ const char *s;
+ unsigned int i;
+ int l, len;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ buf = NULL;
+ len = 0;
+
+ for (i = 0; i < n_desks; i++)
+ {
+ s = (names) ? names[i] : NULL;
+ if (!s)
+ {
+ /* Default to "Desk-<number>" */
+ sprintf(ss, "Desk-%d", i);
+ s = ss;
+ }
+
+ l = strlen(s) + 1;
+ buf = realloc(buf, len + l);
+ memcpy(buf + len, s, l);
+ len += l;
+ }
+
+ _ATOM_SET_UTF8_STRING_LIST(root, ECORE_X_ATOM_NET_DESKTOP_NAMES, buf, len);
+
+ free(buf);
+}
+
+EAPI void
+ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width,
+ unsigned int height)
+{
+ unsigned int size[2];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ size[0] = width;
+ size[1] = height;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, size,
+ 2);
+}
+
+EAPI void
+ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
+ unsigned int *origins, unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
+ origins, 2 * n_desks);
+}
+
+EAPI void
+ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation,
+ int columns, int rows,
+ int starting_corner)
+{
+ unsigned int layout[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ layout[0] = orientation;
+ layout[1] = columns;
+ layout[2] = rows;
+ layout[3] = starting_corner;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT,
+ layout, 4);
+}
+
+EAPI void
+ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
+ unsigned int *areas, unsigned int n_desks)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas,
+ 4 * n_desks);
+}
+
+EAPI void
+ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, &desk,
+ 1);
+}
+
+EAPI void
+ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on)
+{
+ unsigned int val;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ val = (on) ? 1 : 0;
+ ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val,
+ 1);
+}
+
+/*
+ * Client status
+ */
+
+/* Mapping order */
+EAPI void
+ecore_x_netwm_client_list_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients, unsigned int n_clients)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST,
+ p_clients, n_clients);
+}
+
+/* Stacking order */
+EAPI void
+ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
+ Ecore_X_Window *p_clients,
+ unsigned int n_clients)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
+ p_clients, n_clients);
+}
+
+EAPI void
+ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW,
+ &win, 1);
+}
+
+EAPI void
+ecore_x_netwm_client_active_request(Ecore_X_Window root, Ecore_X_Window win, int type, Ecore_X_Window current_win)
+{
+ XEvent xev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_ACTIVE_WINDOW;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = type;
+ xev.xclient.data.l[1] = CurrentTime;
+ xev.xclient.data.l[2] = current_win;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_name_set(Ecore_X_Window win, const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
+}
+
+EAPI int
+ecore_x_netwm_name_get(Ecore_X_Window win, char **name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win, ECORE_X_ATOM_NET_WM_NAME);
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_startup_id_set(Ecore_X_Window win, const char *id)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id);
+}
+
+EAPI int
+ecore_x_netwm_startup_id_get(Ecore_X_Window win, char **id)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (id)
+ *id = _ecore_x_window_prop_string_utf8_get(win, ECORE_X_ATOM_NET_STARTUP_ID);
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
+ name);
+}
+
+EAPI int
+ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME,
+ name);
+}
+
+EAPI int
+ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win,
+ ECORE_X_ATOM_NET_WM_ICON_NAME);
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_prop_string_utf8_set(win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
+ name);
+}
+
+EAPI int
+ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (name)
+ *name = _ecore_x_window_prop_string_utf8_get(win,
+ ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
+}
+
+EAPI int
+ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
+ &tmp, 1);
+
+ if (desk) *desk = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+/*
+ * _NET_WM_STRUT is deprecated
+ */
+EAPI void
+ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right,
+ int top, int bottom)
+{
+ unsigned int strut[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ strut[0] = left;
+ strut[1] = right;
+ strut[2] = top;
+ strut[3] = bottom;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+}
+
+/*
+ * _NET_WM_STRUT is deprecated
+ */
+EAPI int
+ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right,
+ int *top, int *bottom)
+{
+ int ret = 0;
+ unsigned int strut[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
+ if (ret != 4)
+ return 0;
+
+ if (left) *left = strut[0];
+ if (right) *right = strut[1];
+ if (top) *top = strut[2];
+ if (bottom) *bottom = strut[3];
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_strut_partial_set(Ecore_X_Window win, int left, int right,
+ int top, int bottom, int left_start_y, int left_end_y,
+ int right_start_y, int right_end_y, int top_start_x,
+ int top_end_x, int bottom_start_x, int bottom_end_x)
+{
+ unsigned int strut[12];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ strut[0] = left;
+ strut[1] = right;
+ strut[2] = top;
+ strut[3] = bottom;
+ strut[4] = left_start_y;
+ strut[5] = left_end_y;
+ strut[6] = right_start_y;
+ strut[7] = right_end_y;
+ strut[8] = top_start_x;
+ strut[9] = top_end_x;
+ strut[10] = bottom_start_x;
+ strut[11] = bottom_end_x;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
+}
+
+EAPI int
+ecore_x_netwm_strut_partial_get(Ecore_X_Window win, int *left, int *right,
+ int *top, int *bottom, int *left_start_y, int *left_end_y,
+ int *right_start_y, int *right_end_y, int *top_start_x,
+ int *top_end_x, int *bottom_start_x, int *bottom_end_x)
+{
+ int ret = 0;
+ unsigned int strut[12];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
+ if (ret != 12)
+ return 0;
+
+ if (left) *left = strut[0];
+ if (right) *right = strut[1];
+ if (top) *top = strut[2];
+ if (bottom) *bottom = strut[3];
+ if (left_start_y) *left_start_y = strut[4];
+ if (left_end_y) *left_end_y = strut[5];
+ if (right_start_y) *right_start_y = strut[6];
+ if (right_end_y) *right_end_y = strut[7];
+ if (top_start_x) *top_start_x = strut[8];
+ if (top_end_x) *top_end_x = strut[9];
+ if (bottom_start_x) *bottom_start_x = strut[10];
+ if (bottom_end_x) *bottom_end_x = strut[11];
+ return 1;
+}
+
+EAPI int
+ecore_x_netwm_icons_get(Ecore_X_Window win, Ecore_X_Icon **icon, int *num)
+{
+ unsigned int *data, *p;
+ unsigned int *src;
+ unsigned int len, icons, i;
+ int num_ret;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num) *num = 0;
+ if (icon) *icon = NULL;
+
+ num_ret = ecore_x_window_prop_card32_list_get(win, ECORE_X_ATOM_NET_WM_ICON,
+ &data);
+ if (num_ret <= 0)
+ return 0;
+ if (!data) return 0;
+ if (num_ret < 2)
+ {
+ free(data);
+ return 0;
+ }
+
+ /* Check how many icons there are */
+ icons = 0;
+ p = data;
+ while (p)
+ {
+ len = p[0] * p[1];
+ p += (len + 2);
+ if ((p - data) > num_ret)
+ {
+ free(data);
+ return 0;
+ }
+ icons++;
+
+ if ((p - data) == num_ret)
+ p = NULL;
+ }
+ if (num) *num = icons;
+
+ /* If the user doesn't want the icons, return */
+ if (!icon)
+ {
+ free(data);
+ return 1;
+ }
+
+ /* Allocate memory */
+ *icon = malloc(icons * sizeof(Ecore_X_Icon));
+ if (!(*icon))
+ {
+ free(data);
+ return 0;
+ }
+
+ /* Fetch the icons */
+ p = data;
+ for (i = 0; i < icons; i++)
+ {
+ unsigned int *ps, *pd, *pe;
+
+ len = p[0] * p[1];
+ ((*icon)[i]).width = p[0];
+ ((*icon)[i]).height = p[1];
+ src = &(p[2]);
+ ((*icon)[i]).data = malloc(len * sizeof(unsigned int));
+ if (!((*icon)[i]).data)
+ {
+ while (i)
+ free(((*icon)[--i]).data);
+ free(*icon);
+ free(data);
+ return 0;
+ }
+
+ pd = ((*icon)[i]).data;
+ ps = src;
+ pe = ps + len;
+ for (; ps < pe; ps++)
+ {
+ unsigned int r, g, b, a;
+
+ a = (*ps >> 24) & 0xff;
+ r = (((*ps >> 16) & 0xff) * a) / 255;
+ g = (((*ps >> 8) & 0xff) * a) / 255;
+ b = (((*ps ) & 0xff) * a) / 255;
+ *pd = (a << 24) | (r << 16) | (g << 8) | (b);
+ pd++;
+ }
+ p += (len + 2);
+ }
+
+ free(data);
+
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int width, int height)
+{
+ unsigned int geometry[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ geometry[0] = x;
+ geometry[1] = y;
+ geometry[2] = width;
+ geometry[3] = height;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
+}
+
+EAPI int
+ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *width, int *height)
+{
+ int ret;
+ unsigned int geometry[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
+ if (ret != 4)
+ return 0;
+
+ if (x) *x = geometry[0];
+ if (y) *y = geometry[1];
+ if (width) *width = geometry[2];
+ if (height) *height = geometry[3];
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_pid_set(Ecore_X_Window win, int pid)
+{
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ tmp = pid;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+}
+
+EAPI int
+ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID,
+ &tmp, 1);
+ if (pid) *pid = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+EAPI void
+ecore_x_netwm_handled_icons_set(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+}
+
+EAPI int
+ecore_x_netwm_handled_icons_get(Ecore_X_Window win)
+{
+ int ret = 0;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
+ NULL, 0);
+ return ret == 0 ? 1 : 0;
+}
+
+EAPI void
+ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &time, 1);
+}
+
+EAPI int
+ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
+ &tmp, 1);
+ if (time) *time = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+Ecore_X_Window_State
+_ecore_x_netwm_state_get(Ecore_X_Atom a)
+{
+ if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
+ return ECORE_X_WINDOW_STATE_MODAL;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
+ return ECORE_X_WINDOW_STATE_STICKY;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
+ return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
+ return ECORE_X_WINDOW_STATE_SHADED;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
+ return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
+ return ECORE_X_WINDOW_STATE_SKIP_PAGER;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
+ return ECORE_X_WINDOW_STATE_HIDDEN;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
+ return ECORE_X_WINDOW_STATE_FULLSCREEN;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
+ return ECORE_X_WINDOW_STATE_ABOVE;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
+ return ECORE_X_WINDOW_STATE_BELOW;
+ else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
+ return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
+ else
+ return ECORE_X_WINDOW_STATE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
+{
+ switch(s)
+ {
+ case ECORE_X_WINDOW_STATE_MODAL:
+ return ECORE_X_ATOM_NET_WM_STATE_MODAL;
+ case ECORE_X_WINDOW_STATE_STICKY:
+ return ECORE_X_ATOM_NET_WM_STATE_STICKY;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
+ return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
+ case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
+ return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
+ case ECORE_X_WINDOW_STATE_SHADED:
+ return ECORE_X_ATOM_NET_WM_STATE_SHADED;
+ case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
+ return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
+ case ECORE_X_WINDOW_STATE_SKIP_PAGER:
+ return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
+ case ECORE_X_WINDOW_STATE_HIDDEN:
+ return ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
+ case ECORE_X_WINDOW_STATE_FULLSCREEN:
+ return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
+ case ECORE_X_WINDOW_STATE_ABOVE:
+ return ECORE_X_ATOM_NET_WM_STATE_ABOVE;
+ case ECORE_X_WINDOW_STATE_BELOW:
+ return ECORE_X_ATOM_NET_WM_STATE_BELOW;
+ case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
+ return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
+ default:
+ return 0;
+ }
+}
+
+EAPI void
+ecore_x_netwm_window_state_set(Ecore_X_Window win, Ecore_X_Window_State *state, unsigned int num)
+{
+ Ecore_X_Atom *set;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!num)
+ {
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_STATE);
+ return;
+ }
+
+ set = malloc(num * sizeof(Ecore_X_Atom));
+ if (!set) return;
+
+ for (i = 0; i < num; i++)
+ set[i] = _ecore_x_netwm_state_atom_get(state[i]);
+
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num);
+
+ free(set);
+}
+
+EAPI int
+ecore_x_netwm_window_state_get(Ecore_X_Window win, Ecore_X_Window_State **state, unsigned int *num)
+{
+ int num_ret, i;
+ Ecore_X_Atom *atoms;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num) *num = 0;
+ if (state) *state = NULL;
+
+ num_ret = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE,
+ &atoms);
+ if (num_ret <= 0)
+ return 0;
+
+ if (state)
+ {
+ *state = malloc(num_ret * sizeof(Ecore_X_Window_State));
+ if (*state)
+ for (i = 0; i < num_ret; ++i)
+ (*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
+
+ if (num) *num = num_ret;
+ }
+
+ free(atoms);
+ return 1;
+}
+
+static Ecore_X_Window_Type
+_ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
+{
+ if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
+ return ECORE_X_WINDOW_TYPE_DESKTOP;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
+ return ECORE_X_WINDOW_TYPE_DOCK;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
+ return ECORE_X_WINDOW_TYPE_TOOLBAR;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
+ return ECORE_X_WINDOW_TYPE_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
+ return ECORE_X_WINDOW_TYPE_UTILITY;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
+ return ECORE_X_WINDOW_TYPE_SPLASH;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
+ return ECORE_X_WINDOW_TYPE_DIALOG;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
+ return ECORE_X_WINDOW_TYPE_NORMAL;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
+ return ECORE_X_WINDOW_TYPE_DROPDOWN_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU)
+ return ECORE_X_WINDOW_TYPE_POPUP_MENU;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP)
+ return ECORE_X_WINDOW_TYPE_TOOLTIP;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION)
+ return ECORE_X_WINDOW_TYPE_NOTIFICATION;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO)
+ return ECORE_X_WINDOW_TYPE_COMBO;
+ else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND)
+ return ECORE_X_WINDOW_TYPE_DND;
+ else
+ return ECORE_X_WINDOW_TYPE_UNKNOWN;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type)
+{
+ switch (type)
+ {
+ case ECORE_X_WINDOW_TYPE_DESKTOP:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
+ case ECORE_X_WINDOW_TYPE_DOCK:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
+ case ECORE_X_WINDOW_TYPE_TOOLBAR:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
+ case ECORE_X_WINDOW_TYPE_MENU:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
+ case ECORE_X_WINDOW_TYPE_UTILITY:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
+ case ECORE_X_WINDOW_TYPE_SPLASH:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
+ case ECORE_X_WINDOW_TYPE_DIALOG:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
+ case ECORE_X_WINDOW_TYPE_NORMAL:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
+ case ECORE_X_WINDOW_TYPE_DROPDOWN_MENU:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
+ case ECORE_X_WINDOW_TYPE_POPUP_MENU:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU;
+ case ECORE_X_WINDOW_TYPE_TOOLTIP:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP;
+ case ECORE_X_WINDOW_TYPE_NOTIFICATION:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION;
+ case ECORE_X_WINDOW_TYPE_COMBO:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO;
+ case ECORE_X_WINDOW_TYPE_DND:
+ return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
+ * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
+ */
+EAPI void
+ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type)
+{
+ Ecore_X_Atom atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ atom = _ecore_x_netwm_window_type_atom_get(type);
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atom, 1);
+}
+
+/* FIXME: Maybe return 0 on some conditions? */
+EAPI int
+ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type)
+{
+ int num;
+ Ecore_X_Atom *atoms = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (type) *type = ECORE_X_WINDOW_TYPE_NORMAL;
+
+ num = ecore_x_window_prop_atom_list_get(win,
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atoms);
+ if ((type) && (num >= 1) && (atoms))
+ *type = _ecore_x_netwm_window_type_type_get(atoms[0]);
+
+ free(atoms);
+ if (num >= 1) return 1;
+ return 0;
+}
+
+EAPI int
+ecore_x_netwm_window_types_get(Ecore_X_Window win, Ecore_X_Window_Type **types)
+{
+ int num, i;
+ Ecore_X_Atom *atoms = NULL;
+ Ecore_X_Window_Type *atoms2 = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (types) *types = NULL;
+ num = ecore_x_window_prop_atom_list_get(win,
+ ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atoms);
+ if ((num <= 0) || (!atoms))
+ {
+ if (atoms) free(atoms);
+ return 0;
+ }
+ atoms2 = malloc(num * sizeof(Ecore_X_Window_Type));
+ if (!atoms2) return 0;
+ for (i = 0; i < num; i++)
+ atoms2[i] = _ecore_x_netwm_window_type_type_get(atoms[i]);
+ free(atoms);
+ if (types) *types = atoms2;
+ else free(atoms2);
+ return num;
+}
+
+static Ecore_X_Atom
+_ecore_x_netwm_action_atom_get(Ecore_X_Action action)
+{
+ switch (action)
+ {
+ case ECORE_X_ACTION_MOVE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
+ case ECORE_X_ACTION_RESIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
+ case ECORE_X_ACTION_MINIMIZE:
+ return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
+ case ECORE_X_ACTION_SHADE:
+ return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
+ case ECORE_X_ACTION_STICK:
+ return ECORE_X_ATOM_NET_WM_ACTION_STICK;
+ case ECORE_X_ACTION_MAXIMIZE_HORZ:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
+ case ECORE_X_ACTION_MAXIMIZE_VERT:
+ return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
+ case ECORE_X_ACTION_FULLSCREEN:
+ return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
+ case ECORE_X_ACTION_CHANGE_DESKTOP:
+ return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
+ case ECORE_X_ACTION_CLOSE:
+ return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
+ case ECORE_X_ACTION_ABOVE:
+ return ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
+ case ECORE_X_ACTION_BELOW:
+ return ECORE_X_ATOM_NET_WM_ACTION_BELOW;
+ default:
+ return 0;
+ }
+}
+
+/* FIXME: Get complete list */
+EAPI int
+ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action)
+{
+ int num, i, ret = 0;
+ Ecore_X_Atom *atoms, atom;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ num = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
+ &atoms);
+ if (num <= 0)
+ return ret;
+
+ atom = _ecore_x_netwm_action_atom_get(action);
+
+ for (i = 0; i < num; ++i)
+ {
+ if (atom == atoms[i])
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ free(atoms);
+ return ret;
+}
+
+/* FIXME: Set complete list */
+EAPI void
+ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action *action, unsigned int num)
+{
+ Ecore_X_Atom *set;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!num)
+ {
+ ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
+ return;
+ }
+
+ set = malloc(num * sizeof(Ecore_X_Atom));
+ if (!set) return;
+
+ for (i = 0; i < num; i++)
+ set[i] = _ecore_x_netwm_action_atom_get(action[i]);
+
+ ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, set, num);
+
+ free(set);
+}
+
+EAPI int
+ecore_x_netwm_allowed_action_get(Ecore_X_Window win, Ecore_X_Action **action, unsigned int *num)
+{
+ int num_ret, i;
+ Ecore_X_Atom *atoms;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num) *num = 0;
+ if (action) *action = NULL;
+
+ num_ret = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
+ &atoms);
+ if (num_ret <= 0)
+ return 0;
+
+ if (action)
+ {
+ *action = malloc(num_ret * sizeof(Ecore_X_Action));
+ if (*action)
+ for (i = 0; i < num_ret; ++i)
+ (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
+
+ if (num) *num = num_ret;
+ }
+
+ free(atoms);
+ return 1;
+}
+
+EAPI void
+ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &opacity, 1);
+}
+
+EAPI int
+ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
+ &tmp, 1);
+ if (opacity) *opacity = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+EAPI void
+ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb)
+{
+ unsigned int frames[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ frames[0] = fl;
+ frames[1] = fr;
+ frames[2] = ft;
+ frames[3] = fb;
+ ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
+}
+
+EAPI int
+ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb)
+{
+ int ret = 0;
+ unsigned int frames[4];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
+ if (ret != 4)
+ return 0;
+
+ if (fl) *fl = frames[0];
+ if (fr) *fr = frames[1];
+ if (ft) *ft = frames[2];
+ if (fb) *fb = frames[3];
+ return 1;
+}
+
+EAPI int
+ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter)
+{
+ int ret;
+ unsigned int tmp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
+ &tmp, 1);
+
+ if (counter) *counter = tmp;
+ return ret == 1 ? 1 : 0;
+}
+
+EAPI void
+ecore_x_netwm_ping_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ if (!win) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_PING;
+ xev.xclient.data.l[1] = _ecore_x_event_last_time;
+ xev.xclient.data.l[2] = win;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial)
+{
+ XSyncValue value;
+ XEvent xev;
+
+ if (!win) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&value, (int)serial);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
+ xev.xclient.data.l[1] = _ecore_x_event_last_time;
+ xev.xclient.data.l[2] = XSyncValueLow32(value);
+ xev.xclient.data.l[3] = XSyncValueHigh32(value);
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root,
+ Ecore_X_Window_State s1, Ecore_X_Window_State s2, int set)
+{
+ XEvent xev;
+
+ if (!win) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_WM_STATE;
+ xev.xclient.data.l[0] = !!set;
+ xev.xclient.data.l[1] = _ecore_x_netwm_state_atom_get(s1);
+ xev.xclient.data.l[2] = _ecore_x_netwm_state_atom_get(s2);
+ /* 1 == normal client, if someone wants to use this
+ * function in a pager, this should be 2 */
+ xev.xclient.data.l[3] = 1;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+EAPI void
+ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop)
+{
+ XEvent xev;
+
+ if (!win) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!root) root = DefaultRootWindow(_ecore_x_disp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.format = 32;
+ xev.xclient.message_type = ECORE_X_ATOM_NET_WM_DESKTOP;
+ xev.xclient.data.l[0] = desktop;
+
+ XSendEvent(_ecore_x_disp, root, False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xev);
+}
+
+int
+_ecore_x_netwm_startup_info_begin(Ecore_X_Window win __UNUSED__, char *data __UNUSED__)
+{
+#if 0
+ Ecore_X_Startup_Info *info;
+ unsigned char *exists = 0;
+
+ if (!startup_info) return 0;
+ info = eina_hash_find(startup_info, (void *)win);
+ if (info)
+ {
+ exists = 1;
+ WRN("Already got info for win: 0x%x", win);
+ _ecore_x_netwm_startup_info_free(info);
+ }
+ info = calloc(1, sizeof(Ecore_X_Startup_Info));
+ if (!info) return 0;
+ info->win = win;
+ info->length = 0;
+ info->buffer_size = 161;
+ info->buffer = calloc(info->buffer_size, sizeof(char));
+ if (!info->buffer)
+ {
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ memcpy(info->buffer, data, 20);
+ info->length += 20;
+ info->buffer[info->length] = 0;
+ if (exists)
+ eina_hash_modify(startup_info, (void *)info->win, info);
+ else
+ eina_hash_add(startup_info, (void *)info->win, info);
+ if (strlen(info->buffer) != 20)
+ {
+ /* We have a '\0' in there, the message is done */
+ _ecore_x_netwm_startup_info_process(info);
+ }
+#endif
+ return 1;
+}
+
+int
+_ecore_x_netwm_startup_info(Ecore_X_Window win __UNUSED__, char *data __UNUSED__)
+{
+#if 0
+ Ecore_X_Startup_Info *info;
+ char *p;
+
+ if (!startup_info) return 0;
+ info = eina_hash_find(startup_info, (void *)win);
+ if (!info) return 0;
+ if ((info->length + 20) > info->buffer_size)
+ {
+ info->buffer_size += 160;
+ info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char));
+ if (!info->buffer)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ }
+ memcpy(info->buffer + info->length, data, 20);
+ p = info->buffer + info->length;
+ info->length += 20;
+ info->buffer[info->length] = 0;
+ if (strlen(p) != 20)
+ {
+ /* We have a '\0' in there, the message is done */
+ _ecore_x_netwm_startup_info_process(info);
+ }
+#endif
+ return 1;
+}
+
+/*
+ * Set UTF-8 string property
+ */
+static void
+_ecore_x_window_prop_string_utf8_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ const char *str)
+{
+ XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8,
+ PropModeReplace, (unsigned char *)str, strlen(str));
+}
+
+/*
+ * Get UTF-8 string property
+ */
+static char *
+_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win, Ecore_X_Atom atom)
+{
+ char *str;
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+
+ str = NULL;
+ prop_ret = NULL;
+ XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ ECORE_X_ATOM_UTF8_STRING, &type_ret,
+ &format_ret, &num_ret, &bytes_after, &prop_ret);
+ if (prop_ret && num_ret > 0 && format_ret == 8)
+ {
+ str = malloc(num_ret + 1);
+ if (str)
+ {
+ memcpy(str, prop_ret, num_ret);
+ str[num_ret] = '\0';
+ }
+ }
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return str;
+}
+
+#if 0 /* Unused */
+/*
+ * Process startup info
+ */
+static int
+_ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
+{
+ Ecore_X_Event_Startup_Sequence *e;
+ int event;
+ char *p;
+
+ p = strchr(info->buffer, ':');
+ if (!p)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ *p = 0;
+ if (!strcmp(info->buffer, "new"))
+ {
+ if (info->init)
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
+ else
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
+ info->init = 1;
+ }
+ else if (!strcmp(info->buffer, "change"))
+ {
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
+ }
+ else if (!strcmp(info->buffer, "remove"))
+ event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
+ else
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+
+ p++;
+
+ if (!_ecore_x_netwm_startup_info_parse(info, p))
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+
+ if (info->init)
+ {
+ e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence));
+ if (!e)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ return 0;
+ }
+ e->win = info->win;
+ ecore_event_add(event, e, NULL, NULL);
+ }
+
+ if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE)
+ {
+ eina_hash_del(startup_info, (void *)info->win);
+ _ecore_x_netwm_startup_info_free(info);
+ }
+ else
+ {
+ /* Discard buffer */
+ info->length = 0;
+ info->buffer[0] = 0;
+ }
+ return 1;
+}
+
+/*
+ * Parse startup info
+ */
+static int
+_ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, char *data)
+{
+ while (*data)
+ {
+ int in_quot_sing, in_quot_dbl, escaped;
+ char *p, *pp;
+ char *key;
+ char value[1024];
+
+ /* Skip space */
+ while (*data == ' ') data++;
+ /* Get key */
+ key = data;
+ data = strchr(key, '=');
+ if (!data) return 0;
+ *data = 0;
+ data++;
+
+ /* Get value */
+ p = data;
+ pp = value;
+ in_quot_dbl = 0;
+ in_quot_sing = 0;
+ escaped = 0;
+ while (*p)
+ {
+ if ((pp - value) >= 1024) return 0;
+ if (escaped)
+ {
+ *pp = *p;
+ pp++;
+ escaped = 0;
+ }
+ else if (in_quot_sing)
+ {
+ if (*p == '\\')
+ escaped = 1;
+ else if (*p == '\'')
+ in_quot_sing = 0;
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ else if (in_quot_dbl)
+ {
+ if (*p == '\\')
+ escaped = 1;
+ else if (*p == '\"')
+ in_quot_dbl = 0;
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ else
+ {
+ if (*p == '\\')
+ escaped = 1;
+ else if (*p == '\'')
+ in_quot_sing = 1;
+ else if (*p == '\"')
+ in_quot_dbl = 1;
+ else if (*p == ' ')
+ {
+ break;
+ }
+ else
+ {
+ *pp = *p;
+ pp++;
+ }
+ }
+ p++;
+ }
+ if ((in_quot_dbl) || (in_quot_sing)) return 0;
+ data = p;
+ *pp = 0;
+
+ /* Parse info */
+ if (!strcmp(key, "ID"))
+ {
+ if ((info->id) && (strcmp(info->id, value))) return 0;
+ info->id = strdup(value);
+ p = strstr(value, "_TIME");
+ if (p)
+ {
+ info->timestamp = atoi(p + 5);
+ }
+ }
+ else if (!strcmp(key, "NAME"))
+ {
+ if (info->name) free(info->name);
+ info->name = strdup(value);
+ }
+ else if (!strcmp(key, "SCREEN"))
+ {
+ info->screen = atoi(value);
+ }
+ else if (!strcmp(key, "BIN"))
+ {
+ if (info->bin) free(info->bin);
+ info->bin = strdup(value);
+ }
+ else if (!strcmp(key, "ICON"))
+ {
+ if (info->icon) free(info->icon);
+ info->icon = strdup(value);
+ }
+ else if (!strcmp(key, "DESKTOP"))
+ {
+ info->desktop = atoi(value);
+ }
+ else if (!strcmp(key, "TIMESTAMP"))
+ {
+ if (!info->timestamp)
+ info->timestamp = atoi(value);
+ }
+ else if (!strcmp(key, "DESCRIPTION"))
+ {
+ if (info->description) free(info->description);
+ info->description = strdup(value);
+ }
+ else if (!strcmp(key, "WMCLASS"))
+ {
+ if (info->wmclass) free(info->wmclass);
+ info->wmclass = strdup(value);
+ }
+ else if (!strcmp(key, "SILENT"))
+ {
+ info->silent = atoi(value);
+ }
+ else
+ {
+ ERR("Ecore X Sequence, Unknown: %s=%s", key, value);
+ }
+ }
+ if (!info->id) return 0;
+ return 1;
+}
+#endif
+
+/*
+ * Free startup info struct
+ */
+static void
+_ecore_x_netwm_startup_info_free(void *data)
+{
+ Ecore_X_Startup_Info *info;
+
+ info = data;
+ if (!info) return;
+ if (info->buffer) free(info->buffer);
+ if (info->id) free(info->id);
+ if (info->name) free(info->name);
+ if (info->bin) free(info->bin);
+ if (info->icon) free(info->icon);
+ if (info->description) free(info->description);
+ if (info->wmclass) free(info->wmclass);
+ free(info);
+}
+
+/*
+ * Is screen composited?
+ */
+EAPI int
+ecore_x_screen_is_composited(int screen)
+{
+ Ecore_X_Window win;
+ static Ecore_X_Atom atom = None;
+ char buf[32];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
+ if (atom == None) atom = XInternAtom(_ecore_x_disp, buf, False);
+ if (atom == None) return 0;
+
+ win = XGetSelectionOwner(_ecore_x_disp, atom);
+
+ return win != None;
+}
+
+EAPI void
+ecore_x_screen_is_composited_set(int screen, Ecore_X_Window win)
+{
+ static Ecore_X_Atom atom = None;
+ char buf[32];
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
+ if (atom == None) atom = XInternAtom(_ecore_x_disp, buf, False);
+ if (atom == None) return;
+ XSetSelectionOwner(_ecore_x_disp, atom, win, _ecore_x_event_last_time);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * @defgroup Ecore_X_Pixmap_Group X Pixmap Functions
+ *
+ * Functions that operate on pixmaps.
+ */
+
+/**
+ * Creates a new pixmap.
+ * @param win Window used to determine which screen of the display the
+ * pixmap should be created on. If 0, the default root window
+ * is used.
+ * @param w Width of the new pixmap.
+ * @param h Height of the new pixmap.
+ * @param dep Depth of the pixmap. If 0, the default depth of the default
+ * screen is used.
+ * @return New pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI Ecore_X_Pixmap
+ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (dep == 0) dep = DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
+ return XCreatePixmap(_ecore_x_disp, win, w, h, dep);
+}
+
+/**
+ * Deletes the reference to the given pixmap.
+ *
+ * If no other clients have a reference to the given pixmap, the server
+ * will destroy it.
+ *
+ * @param pmap The given pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_free(Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XFreePixmap(_ecore_x_disp, pmap);
+}
+
+/**
+ * Pastes a rectangular area of the given pixmap onto the given drawable.
+ * @param pmap The given pixmap.
+ * @param dest The given drawable.
+ * @param gc The graphics context which governs which operation will
+ * be used to paste the area onto the drawable.
+ * @param sx The X position of the area on the pixmap.
+ * @param sy The Y position of the area on the pixmap.
+ * @param w The width of the area.
+ * @param h The height of the area.
+ * @param dx The X position at which to paste the area on @p dest.
+ * @param dy The Y position at which to paste the area on @p dest.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, Ecore_X_Drawable dest,
+ Ecore_X_GC gc, int sx, int sy,
+ int w, int h, int dx, int dy)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XCopyArea(_ecore_x_disp, pmap, dest, gc, sx, sy, w, h, dx, dy);
+}
+
+/**
+ * Retrieves the size of the given pixmap.
+ * @param pmap The given pixmap.
+ * @param x Pointer to an integer in which to store the X position.
+ * @param y Pointer to an integer in which to store the Y position.
+ * @param w Pointer to an integer in which to store the width.
+ * @param h Pointer to an integer in which to store the height.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI void
+ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (pmap) ecore_x_drawable_geometry_get(pmap, x, y, w, h);
+}
+
+/**
+ * Retrieves the depth of the given pixmap.
+ * @param pmap The given pixmap.
+ * @return The depth of the pixmap.
+ * @ingroup Ecore_X_Pixmap_Group
+ */
+EAPI int
+ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_drawable_depth_get(pmap);
+}
+
--- /dev/null
+#ifndef _ECORE_X_PRIVATE_H
+#define _ECORE_X_PRIVATE_H
+
+#include <sys/param.h>
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+#define XK_MISCELLANY 1
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xresource.h>
+#include <X11/keysymdef.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
+#include <X11/extensions/sync.h>
+#include <X11/extensions/dpms.h>
+#ifdef ECORE_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif
+#ifdef ECORE_XPRINT
+#include <X11/extensions/Print.h>
+#endif
+#ifdef ECORE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+#ifdef ECORE_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
+#ifdef ECORE_XSS
+#include <X11/extensions/scrnsaver.h>
+#endif
+#ifdef ECORE_XRENDER
+#include <X11/extensions/Xrender.h>
+#endif
+#ifdef ECORE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+#ifdef ECORE_XCOMPOSITE
+#include <X11/extensions/Xcomposite.h>
+#endif
+#ifdef ECORE_XDAMAGE
+#include <X11/extensions/Xdamage.h>
+#endif
+#ifdef ECORE_XDPMS
+#include <X11/extensions/dpms.h>
+#endif
+#ifdef ECORE_XKB
+#include <X11/XKBlib.h>
+#endif
+#ifdef ECORE_XI2
+#include <X11/extensions/XInput2.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_X.h"
+#include "Ecore_Input.h"
+
+extern int _ecore_xlib_log_dom;
+#ifdef ECORE_XLIB_DEFAULT_LOG_COLOR
+# undef ECORE_XLIB_DEFAULT_LOG_COLOR
+#endif
+#define ECORE_XLIB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_ecore_xlib_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_xlib_log_dom, __VA_ARGS__)
+
+typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern;
+
+struct _Ecore_X_Selection_Intern
+{
+ Ecore_X_Window win;
+ Ecore_X_Atom selection;
+ unsigned char *data;
+ int length;
+ Time time;
+};
+
+typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter;
+
+struct _Ecore_X_Selection_Converter
+{
+ Ecore_X_Atom target;
+ int (*convert)(char *target, void *data, int size,
+ void **data_ret, int *size_ret);
+ Ecore_X_Selection_Converter *next;
+};
+
+typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser;
+
+struct _Ecore_X_Selection_Parser
+{
+ char *target;
+ void *(*parse)(const char *target, void *data, int size, int format);
+ Ecore_X_Selection_Parser *next;
+};
+
+typedef struct _Ecore_X_DND_Source
+{
+ int version;
+ Ecore_X_Window win, dest;
+
+ enum {
+ ECORE_X_DND_SOURCE_IDLE,
+ ECORE_X_DND_SOURCE_DRAGGING,
+ ECORE_X_DND_SOURCE_DROPPED,
+ ECORE_X_DND_SOURCE_CONVERTING
+ } state;
+
+ struct {
+ short x, y;
+ unsigned short width, height;
+ } rectangle;
+
+ struct {
+ Ecore_X_Window window;
+ int x, y;
+ } prev;
+
+ Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+ int suppress;
+
+ int await_status;
+} Ecore_X_DND_Source;
+
+typedef struct _Ecore_X_DND_Target
+{
+ int version;
+ Ecore_X_Window win, source;
+
+ enum {
+ ECORE_X_DND_TARGET_IDLE,
+ ECORE_X_DND_TARGET_ENTERED
+ } state;
+
+ struct {
+ int x, y;
+ } pos;
+
+ Time time;
+
+ Ecore_X_Atom action, accepted_action;
+
+ int will_accept;
+} Ecore_X_DND_Target;
+
+
+extern int ECORE_X_MODIFIER_SHIFT;
+extern int ECORE_X_MODIFIER_CTRL;
+extern int ECORE_X_MODIFIER_ALT;
+extern int ECORE_X_MODIFIER_WIN;
+
+extern int ECORE_X_LOCK_SCROLL;
+extern int ECORE_X_LOCK_NUM;
+extern int ECORE_X_LOCK_CAPS;
+
+extern Display *_ecore_x_disp;
+extern double _ecore_x_double_click_time;
+extern Time _ecore_x_event_last_time;
+extern Window _ecore_x_event_last_win;
+extern int _ecore_x_event_last_root_x;
+extern int _ecore_x_event_last_root_y;
+extern int _ecore_x_xcursor;
+extern XIC _ecore_x_ic;
+
+extern Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
+
+extern int _ecore_window_grabs_num;
+extern Window *_ecore_window_grabs;
+extern int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event);
+extern void *_ecore_window_grab_replay_data;
+
+extern Ecore_X_Window _ecore_x_private_win;
+
+void _ecore_x_error_handler_init(void);
+void _ecore_x_event_handle_any_event(XEvent *xevent);
+void _ecore_x_event_handle_key_press(XEvent *xevent);
+void _ecore_x_event_handle_key_release(XEvent *xevent);
+void _ecore_x_event_handle_button_press(XEvent *xevent);
+void _ecore_x_event_handle_button_release(XEvent *xevent);
+void _ecore_x_event_handle_motion_notify(XEvent *xevent);
+void _ecore_x_event_handle_enter_notify(XEvent *xevent);
+void _ecore_x_event_handle_leave_notify(XEvent *xevent);
+void _ecore_x_event_handle_focus_in(XEvent *xevent);
+void _ecore_x_event_handle_focus_out(XEvent *xevent);
+void _ecore_x_event_handle_keymap_notify(XEvent *xevent);
+void _ecore_x_event_handle_expose(XEvent *xevent);
+void _ecore_x_event_handle_graphics_expose(XEvent *xevent);
+void _ecore_x_event_handle_visibility_notify(XEvent *xevent);
+void _ecore_x_event_handle_create_notify(XEvent *xevent);
+void _ecore_x_event_handle_destroy_notify(XEvent *xevent);
+void _ecore_x_event_handle_unmap_notify(XEvent *xevent);
+void _ecore_x_event_handle_map_notify(XEvent *xevent);
+void _ecore_x_event_handle_map_request(XEvent *xevent);
+void _ecore_x_event_handle_reparent_notify(XEvent *xevent);
+void _ecore_x_event_handle_configure_notify(XEvent *xevent);
+void _ecore_x_event_handle_configure_request(XEvent *xevent);
+void _ecore_x_event_handle_gravity_notify(XEvent *xevent);
+void _ecore_x_event_handle_resize_request(XEvent *xevent);
+void _ecore_x_event_handle_circulate_notify(XEvent *xevent);
+void _ecore_x_event_handle_circulate_request(XEvent *xevent);
+void _ecore_x_event_handle_property_notify(XEvent *xevent);
+void _ecore_x_event_handle_selection_clear(XEvent *xevent);
+void _ecore_x_event_handle_selection_request(XEvent *xevent);
+void _ecore_x_event_handle_selection_notify(XEvent *xevent);
+void _ecore_x_event_handle_colormap_notify(XEvent *xevent);
+void _ecore_x_event_handle_client_message(XEvent *xevent);
+void _ecore_x_event_handle_mapping_notify(XEvent *xevent);
+void _ecore_x_event_handle_shape_change(XEvent *xevent);
+void _ecore_x_event_handle_screensaver_notify(XEvent *xevent);
+void _ecore_x_event_handle_sync_counter(XEvent *xevent);
+void _ecore_x_event_handle_sync_alarm(XEvent *xevent);
+#ifdef ECORE_XRANDR
+void _ecore_x_event_handle_randr_change(XEvent *xevent);
+void _ecore_x_event_handle_randr_notify(XEvent *xevent);
+#endif
+#ifdef ECORE_XFIXES
+void _ecore_x_event_handle_fixes_selection_notify(XEvent *xevent);
+#endif
+#ifdef ECORE_XDAMAGE
+void _ecore_x_event_handle_damage_notify(XEvent *xevent);
+#endif
+void _ecore_x_event_handle_generic_event(XEvent *xevent);
+
+void _ecore_x_selection_data_init(void);
+void _ecore_x_selection_shutdown(void);
+Ecore_X_Atom
+ _ecore_x_selection_target_atom_get(const char *target);
+char *_ecore_x_selection_target_get(Ecore_X_Atom target);
+Ecore_X_Selection_Intern *
+ _ecore_x_selection_get(Ecore_X_Atom selection);
+int _ecore_x_selection_set(Window w, const void *data, int len, Ecore_X_Atom selection);
+int _ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret);
+void *_ecore_x_selection_parse(const char *target, void *data, int size, int format);
+
+void _ecore_x_sync_magic_send(int val, Ecore_X_Window swin);
+void _ecore_x_window_grab_remove(Ecore_X_Window win);
+void _ecore_x_key_grab_remove(Ecore_X_Window win);
+
+/* from dnd */
+void _ecore_x_dnd_init(void);
+Ecore_X_DND_Source *_ecore_x_dnd_source_get(void);
+Ecore_X_DND_Target *_ecore_x_dnd_target_get(void);
+void _ecore_x_dnd_drag(Ecore_X_Window root, int x, int y);
+void _ecore_x_dnd_shutdown(void);
+
+/* from netwm */
+Ecore_X_Window_State _ecore_x_netwm_state_get(Ecore_X_Atom a);
+int _ecore_x_netwm_startup_info_begin(Ecore_X_Window win, char *data);
+int _ecore_x_netwm_startup_info(Ecore_X_Window win, char *data);
+
+/* Fixes * Damage * Composite * DPMS */
+void _ecore_x_fixes_init(void);
+void _ecore_x_damage_init(void);
+void _ecore_x_composite_init(void);
+void _ecore_x_dpms_init(void);
+void _ecore_x_randr_init(void);
+
+void _ecore_x_atoms_init(void);
+
+extern int _ecore_x_xi2_opcode;
+
+void _ecore_x_input_init(void);
+void _ecore_x_input_shutdown(void);
+void _ecore_x_input_handler(XEvent* xevent);
+/* from sync */
+
+void _ecore_mouse_move(unsigned int timestamp, unsigned int xmodifiers, int x, int y, int x_root, int y_root, unsigned int event_window, unsigned int window, unsigned int root_win, int same_screen, int dev, double radx, double rady, double pressure, double angle, double mx, double my, double mrx, double mry);
+Ecore_Event_Mouse_Button *_ecore_mouse_button(int event, unsigned int timestamp, unsigned int xmodifiers, unsigned int buttons, int x, int y, int x_root, int y_root, unsigned int event_window, unsigned int window, unsigned int root_win, int same_screen, int dev, double radx, double rady, double pressure, double angle, double mx, double my, double mrx, double mry);
+
+//#define LOGFNS 1
+
+#ifdef LOGFNS
+#define LOGFN(fl, ln, fn) printf("-ECORE-X: %25s: %5i - %s\n", fl, ln, fn);
+#else
+#define LOGFN(fl, ln, fn)
+#endif
+
+#endif
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "ecore_x_private.h"
+
+static int _randr_available = 0;
+#ifdef ECORE_XRANDR
+static int _randr_major, _randr_minor, _randr_version;
+#define RANDR_1_2 ((1 << 16) | 2)
+#define RANDR_1_3 ((1 << 16) | 3)
+#endif
+
+void
+_ecore_x_randr_init(void)
+{
+#ifdef ECORE_XRANDR
+ _randr_major = 1;
+ _randr_minor = 3;
+ _randr_version = 0;
+
+ if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor))
+ {
+ _randr_version = (_randr_major << 16) | _randr_minor;
+ _randr_available = 1;
+ }
+ else
+ _randr_available = 0;
+#else
+ _randr_available = 0;
+#endif
+}
+
+EAPI int
+ecore_x_randr_query(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _randr_available;
+}
+
+EAPI int
+ecore_x_randr_events_select(Ecore_X_Window win, int on)
+{
+#ifdef ECORE_XRANDR
+ int mask;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!on)
+ mask = 0;
+ else
+ {
+ mask = RRScreenChangeNotifyMask;
+ if (_randr_version >= RANDR_1_2)
+ mask |= (RRCrtcChangeNotifyMask |
+ RROutputChangeNotifyMask |
+ RROutputPropertyNotifyMask);
+ }
+
+ XRRSelectInput(_ecore_x_disp, win, mask);
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+EAPI Ecore_X_Randr_Rotation
+ecore_x_randr_screen_rotations_get(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+ Rotation rot, crot;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rot = XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &crot);
+ return rot;
+#else
+ return 0;
+#endif
+}
+
+EAPI Ecore_X_Randr_Rotation
+ecore_x_randr_screen_rotation_get(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+ Rotation crot = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &crot);
+ return crot;
+#else
+ return 0;
+#endif
+}
+
+EAPI void
+ecore_x_randr_screen_rotation_set(Ecore_X_Window root, Ecore_X_Randr_Rotation rot)
+{
+#ifdef ECORE_XRANDR
+ XRRScreenConfiguration *xrrcfg;
+ SizeID sizeid;
+ Rotation crot;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xrrcfg = XRRGetScreenInfo(_ecore_x_disp, root);
+ if (!xrrcfg) return;
+ sizeid = XRRConfigCurrentConfiguration(xrrcfg, &crot);
+ XRRSetScreenConfig(_ecore_x_disp, xrrcfg, root, sizeid, rot, CurrentTime);
+ XRRFreeScreenConfigInfo(xrrcfg);
+#endif
+}
+
+EAPI Ecore_X_Screen_Size *
+ecore_x_randr_screen_sizes_get(Ecore_X_Window root, int *num)
+{
+#ifdef ECORE_XRANDR
+ Ecore_X_Screen_Size *ret;
+ XRRScreenSize *sizes;
+ int i, n;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num) *num = 0;
+
+ /* we don't have to free sizes, no idea why not */
+ sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
+ ret = calloc(n, sizeof(Ecore_X_Screen_Size));
+ if (!ret) return NULL;
+
+ if (num) *num = n;
+ for (i = 0; i < n; i++)
+ {
+ ret[i].width = sizes[i].width;
+ ret[i].height = sizes[i].height;
+ }
+ return ret;
+#else
+ if (num) *num = 0;
+ return NULL;
+#endif
+}
+
+EAPI Ecore_X_Screen_Size
+ecore_x_randr_current_screen_size_get(Ecore_X_Window root)
+{
+ Ecore_X_Screen_Size ret = { -1, -1 };
+#ifdef ECORE_XRANDR
+ XRRScreenSize *sizes;
+ XRRScreenConfiguration *sc;
+ SizeID size_index;
+ Rotation rotation;
+ int n;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ sc = XRRGetScreenInfo(_ecore_x_disp, root);
+ if (!sc)
+ {
+ ERR("Couldn't get screen information for %d", root);
+ return ret;
+ }
+ size_index = XRRConfigCurrentConfiguration(sc, &rotation);
+
+ sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
+ if (size_index < n)
+ {
+ ret.width = sizes[size_index].width;
+ ret.height = sizes[size_index].height;
+ }
+ XRRFreeScreenConfigInfo(sc);
+#endif
+ return ret;
+}
+
+EAPI int
+ecore_x_randr_screen_size_set(Ecore_X_Window root, Ecore_X_Screen_Size size)
+{
+#ifdef ECORE_XRANDR
+ XRRScreenConfiguration *sc;
+ XRRScreenSize *sizes;
+ int i, n, size_index = -1;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
+ for (i = 0; i < n; i++)
+ {
+ if ((sizes[i].width == size.width) && (sizes[i].height == size.height))
+ {
+ size_index = i;
+ break;
+ }
+ }
+ if (size_index == -1) return 0;
+
+ sc = XRRGetScreenInfo(_ecore_x_disp, root);
+ if (XRRSetScreenConfig(_ecore_x_disp, sc,
+ root, size_index,
+ RR_Rotate_0, CurrentTime))
+ {
+ ERR("Can't set new screen size!");
+ XRRFreeScreenConfigInfo(sc);
+ return 0;
+ }
+ XRRFreeScreenConfigInfo(sc);
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+EAPI Ecore_X_Screen_Refresh_Rate
+ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root)
+{
+ Ecore_X_Screen_Refresh_Rate ret = { -1 };
+#ifdef ECORE_XRANDR
+ XRRScreenConfiguration *sc;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ sc = XRRGetScreenInfo(_ecore_x_disp, root);
+ if (!sc)
+ {
+ ERR("Couldn't get screen information for %d", root);
+ return ret;
+ }
+ ret.rate = XRRConfigCurrentRate(sc);
+ XRRFreeScreenConfigInfo(sc);
+#endif
+ return ret;
+}
+
+EAPI Ecore_X_Screen_Refresh_Rate *
+ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root, int size_id, int *num)
+{
+#ifdef ECORE_XRANDR
+ Ecore_X_Screen_Refresh_Rate *ret = NULL;
+ XRRScreenConfiguration *sc;
+ short *rates;
+ int i, n;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num) *num = 0;
+
+ sc = XRRGetScreenInfo(_ecore_x_disp, root);
+ if (!sc)
+ {
+ ERR("Couldn't get screen information for %d", root);
+ return ret;
+ }
+
+ rates = XRRRates(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), size_id, &n);
+ ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
+ if (!ret)
+ {
+ XRRFreeScreenConfigInfo(sc);
+ return NULL;
+ }
+
+ if (num) *num = n;
+ for (i = 0; i < n; i++)
+ {
+ ret[i].rate = rates[i];
+ }
+ XRRFreeScreenConfigInfo(sc);
+ return ret;
+#else
+ if (num) *num = 0;
+ return NULL;
+#endif
+}
+
+EAPI int
+ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window root, Ecore_X_Screen_Size size, Ecore_X_Screen_Refresh_Rate rate)
+{
+#ifdef ECORE_XRANDR
+ XRRScreenConfiguration *sc;
+ XRRScreenSize *sizes;
+ int i, n, size_index = -1;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
+ for (i = 0; i < n; i++)
+ {
+ if ((sizes[i].width == size.width) && (sizes[i].height == size.height))
+ {
+ size_index = i;
+ break;
+ }
+ }
+ if (size_index == -1) return 0;
+
+ sc = XRRGetScreenInfo(_ecore_x_disp, root);
+ if (XRRSetScreenConfigAndRate(_ecore_x_disp, sc,
+ root, size_index,
+ RR_Rotate_0, rate.rate, CurrentTime))
+ {
+ ERR("Can't set new screen size and refresh rate!");
+ XRRFreeScreenConfigInfo(sc);
+ return 0;
+ }
+ XRRFreeScreenConfigInfo(sc);
+ return 1;
+#else
+ return 1;
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+
+
+/*
+ * [x] XCreateRegion
+ * [ ] XPolygonRegion
+ * [x] XSetRegion
+ * [x] XDestroyRegion
+ *
+ * [x] XOffsetRegion
+ * [ ] XShrinkRegion
+ *
+ * [ ] XClipBox
+ * [x] XIntersectRegion
+ * [x] XUnionRegion
+ * [x] XUnionRectWithRegion
+ * [x] XSubtractRegion
+ * [ ] XXorRegion
+ *
+ * [x] XEmptyRegion
+ * [x] XEqualRegion
+ *
+ * [x] XPointInRegion
+ * [x] XRectInRegion
+ */
+
+EAPI Ecore_X_XRegion *
+ecore_x_xregion_new()
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return (Ecore_X_XRegion *)XCreateRegion();
+}
+
+EAPI void
+ecore_x_xregion_free(Ecore_X_XRegion *region)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!region)
+ return;
+
+ XDestroyRegion((Region)region);
+}
+
+EAPI int
+ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XSetRegion(_ecore_x_disp, gc, (Region)region);
+}
+
+EAPI void
+ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!region)
+ return;
+
+ /* return value not used */
+ XOffsetRegion((Region)region, x, y);
+}
+
+EAPI int
+ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XIntersectRegion((Region)r1, (Region)r2, (Region)dst);
+}
+
+EAPI int
+ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XUnionRegion((Region)r1, (Region)r2, (Region)dst);
+}
+
+EAPI int
+ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect)
+{
+ XRectangle xr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xr.x = rect->x;
+ xr.y = rect->y;
+ xr.width = rect->width;
+ xr.height = rect->height;
+
+ return XUnionRectWithRegion(&xr, (Region)src, (Region)dst);
+}
+
+EAPI int
+ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *rm, Ecore_X_XRegion *rs)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XSubtractRegion((Region)rm, (Region)rs, (Region)dst);
+}
+
+EAPI int
+ecore_x_xregion_is_empty(Ecore_X_XRegion *region)
+{
+ if (!region)
+ return 1;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return !XEmptyRegion((Region)region);
+}
+
+EAPI int
+ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2)
+{
+ if (!r1 || !r2)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XEqualRegion((Region)r1, (Region)r1);
+}
+
+EAPI int
+ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y)
+{
+ if (!region)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XPointInRegion((Region)region, x, y);
+}
+
+EAPI int
+ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect)
+{
+ if (!region || !rect)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XRectInRegion((Region)region, rect->x, rect->y, rect->width, rect->height);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * Screensaver code
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static int _screensaver_available = -1;
+
+EAPI int
+ecore_x_screensaver_event_available_get(void)
+{
+ if (_screensaver_available >= 0) return _screensaver_available;
+#ifdef ECORE_XSS
+ int _screensaver_major, _screensaver_minor;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _screensaver_major = 1;
+ _screensaver_minor = 0;
+
+ if (XScreenSaverQueryVersion(_ecore_x_disp, &_screensaver_major, &_screensaver_minor))
+ _screensaver_available = 1;
+ else
+ _screensaver_available = 0;
+#else
+ _screensaver_available = 0;
+#endif
+ return _screensaver_available;
+}
+
+EAPI int
+ecore_x_screensaver_idle_time_get(void)
+{
+#ifdef ECORE_XSS
+ XScreenSaverInfo *xss;
+ int idle;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xss = XScreenSaverAllocInfo();
+ XScreenSaverQueryInfo(_ecore_x_disp, RootWindow(_ecore_x_disp, DefaultScreen(_ecore_x_disp)), xss);
+ idle = xss->idle / 1000;
+ XFree(xss);
+
+ return idle;
+#endif
+
+ return 0;
+}
+
+EAPI void
+ecore_x_screensaver_set(int timeout, int interval, int prefer_blanking, int allow_exposures)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetScreenSaver(_ecore_x_disp, timeout, interval, prefer_blanking, allow_exposures);
+}
+
+EAPI void
+ecore_x_screensaver_timeout_set(int timeout)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, timeout, pint, pblank, pexpo);
+}
+
+EAPI int
+ecore_x_screensaver_timeout_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pto;
+}
+
+EAPI void
+ecore_x_screensaver_blank_set(int blank)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, pto, pint, blank, pexpo);
+}
+
+EAPI int
+ecore_x_screensaver_blank_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pblank;
+}
+
+EAPI void
+ecore_x_screensaver_expose_set(int expose)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, pto, pint, pblank, expose);
+}
+
+EAPI int
+ecore_x_screensaver_expose_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pexpo;
+}
+
+EAPI void
+ecore_x_screensaver_interval_set(int interval)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ XSetScreenSaver(_ecore_x_disp, pto, interval, pblank, pexpo);
+}
+
+EAPI int
+ecore_x_screensaver_interval_get(void)
+{
+ int pto, pint, pblank, pexpo;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XGetScreenSaver(_ecore_x_disp, &pto, &pint, &pblank, &pexpo);
+ return pint;
+}
+
+EAPI void
+ecore_x_screensaver_event_listen_set(int on)
+{
+#ifdef ECORE_XSS
+ Ecore_X_Window root;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ root = DefaultRootWindow(_ecore_x_disp);
+ if (on)
+ XScreenSaverSelectInput(_ecore_x_disp, root, ScreenSaverNotifyMask);
+ else
+ XScreenSaverSelectInput(_ecore_x_disp, root, 0);
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static Ecore_X_Selection_Intern selections[4];
+static Ecore_X_Selection_Converter *converters = NULL;
+static Ecore_X_Selection_Parser *parsers = NULL;
+
+static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret);
+static int _ecore_x_selection_data_default_free(void *data);
+static void *_ecore_x_selection_parser_files(const char *target, void *data, int size, int format);
+static int _ecore_x_selection_data_files_free(void *data);
+static void *_ecore_x_selection_parser_text(const char *target, void *data, int size, int format);
+static int _ecore_x_selection_data_text_free(void *data);
+static void *_ecore_x_selection_parser_targets(const char *target, void *data, int size, int format);
+static int _ecore_x_selection_data_targets_free(void *data);
+
+#define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
+
+void
+_ecore_x_selection_data_init(void)
+{
+ /* Initialize global data */
+ memset(selections, 0, sizeof(selections));
+
+ /* Initialize converters */
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT,
+ _ecore_x_selection_converter_text);
+#ifdef X_HAVE_UTF8_STRING
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING,
+ _ecore_x_selection_converter_text);
+#endif
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT,
+ _ecore_x_selection_converter_text);
+ ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING,
+ _ecore_x_selection_converter_text);
+
+ /* Initialize parsers */
+ ecore_x_selection_parser_add("text/plain",
+ _ecore_x_selection_parser_text);
+ ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING,
+ _ecore_x_selection_parser_text);
+ ecore_x_selection_parser_add("text/uri-list",
+ _ecore_x_selection_parser_files);
+ ecore_x_selection_parser_add("_NETSCAPE_URL",
+ _ecore_x_selection_parser_files);
+ ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS,
+ _ecore_x_selection_parser_targets);
+}
+
+void
+_ecore_x_selection_shutdown(void)
+{
+ Ecore_X_Selection_Converter *cnv;
+ Ecore_X_Selection_Parser *prs;
+
+ /* free the selection converters */
+ cnv = converters;
+ while (cnv)
+ {
+ Ecore_X_Selection_Converter *tmp;
+
+ tmp = cnv->next;
+ free(cnv);
+ cnv = tmp;
+ }
+ converters = NULL;
+
+ /* free the selection parsers */
+ prs = parsers;
+ while (prs)
+ {
+ Ecore_X_Selection_Parser *tmp;
+
+ tmp = prs;
+ prs = prs->next;
+ free(tmp->target);
+ free(tmp);
+ }
+ parsers = NULL;
+}
+
+Ecore_X_Selection_Intern *
+_ecore_x_selection_get(Ecore_X_Atom selection)
+{
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ return &selections[0];
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ return &selections[1];
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ return &selections[2];
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ return &selections[3];
+ else
+ return NULL;
+}
+
+int
+_ecore_x_selection_set(Window w, const void *data, int size, Ecore_X_Atom selection)
+{
+ int in;
+ unsigned char *buf = NULL;
+
+ XSetSelectionOwner(_ecore_x_disp, selection, w, _ecore_x_event_last_time);
+ if (XGetSelectionOwner(_ecore_x_disp, selection) != w)
+ return 0;
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ in = 0;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ in = 1;
+ else if (selection == ECORE_X_ATOM_SELECTION_XDND)
+ in = 2;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ in = 3;
+ else
+ return 0;
+
+ if (data)
+ {
+ selections[in].win = w;
+ selections[in].selection = selection;
+ selections[in].length = size;
+ selections[in].time = _ecore_x_event_last_time;
+
+ buf = malloc(size);
+ memcpy(buf, data, size);
+ selections[in].data = buf;
+ }
+ else
+ {
+ if (selections[in].data)
+ {
+ free(selections[in].data);
+ memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data));
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * Claim ownership of the PRIMARY selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ */
+EAPI int
+ecore_x_selection_primary_set(Ecore_X_Window w, const void *data, int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+/**
+ * Release ownership of the primary selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+EAPI int
+ecore_x_selection_primary_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY);
+}
+
+/**
+ * Claim ownership of the SECONDARY selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ */
+EAPI int
+ecore_x_selection_secondary_set(Ecore_X_Window w, const void *data, int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+/**
+ * Release ownership of the secondary selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+EAPI int
+ecore_x_selection_secondary_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_SECONDARY);
+}
+
+/**
+ * Claim ownership of the XDND selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ */
+EAPI int
+ecore_x_selection_xdnd_set(Ecore_X_Window w, const void *data, int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_XDND);
+}
+
+/**
+ * Release ownership of the XDND selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+EAPI int
+ecore_x_selection_xdnd_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_XDND);
+}
+
+/**
+ * Claim ownership of the CLIPBOARD selection and set its data.
+ * @param w The window to which this selection belongs
+ * @param data The data associated with the selection
+ * @param size The size of the data buffer in bytes
+ * @return Returns 1 if the ownership of the selection was successfully
+ * claimed, or 0 if unsuccessful.
+ *
+ * Get the converted data from a previous CLIPBOARD selection
+ * request. The buffer must be freed when done with.
+ */
+EAPI int
+ecore_x_selection_clipboard_set(Ecore_X_Window w, const void *data, int size)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+/**
+ * Release ownership of the clipboard selection
+ * @return Returns 1 if the selection was successfully cleared,
+ * or 0 if unsuccessful.
+ *
+ */
+EAPI int
+ecore_x_selection_clipboard_clear(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_CLIPBOARD);
+}
+
+Ecore_X_Atom
+_ecore_x_selection_target_atom_get(const char *target)
+{
+ Ecore_X_Atom x_target;
+
+ if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
+ x_target = ECORE_X_ATOM_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
+ x_target = ECORE_X_ATOM_COMPOUND_TEXT;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
+ x_target = ECORE_X_ATOM_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
+ x_target = ECORE_X_ATOM_UTF8_STRING;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME))
+ x_target = ECORE_X_ATOM_FILE_NAME;
+ else
+ {
+ x_target = ecore_x_atom_get(target);
+ }
+
+ return x_target;
+}
+
+char *
+_ecore_x_selection_target_get(Ecore_X_Atom target)
+{
+ /* FIXME: Should not return mem allocated with strdup or X mixed,
+ * one should use free to free, the other XFree */
+ if (target == ECORE_X_ATOM_FILE_NAME)
+ return strdup(ECORE_X_SELECTION_TARGET_FILENAME);
+ else if (target == ECORE_X_ATOM_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_STRING);
+ else if (target == ECORE_X_ATOM_UTF8_STRING)
+ return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING);
+ else if (target == ECORE_X_ATOM_TEXT)
+ return strdup(ECORE_X_SELECTION_TARGET_TEXT);
+ else
+ return XGetAtomName(_ecore_x_disp, target);
+}
+
+static void
+_ecore_x_selection_request(Ecore_X_Window w, Ecore_X_Atom selection, const char *target_str)
+{
+ Ecore_X_Atom target, prop;
+
+ target = _ecore_x_selection_target_atom_get(target_str);
+
+ if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
+ prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
+ prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
+ else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
+ prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
+ else
+ return;
+
+ XConvertSelection(_ecore_x_disp, selection, target, prop,
+ w, CurrentTime);
+}
+
+EAPI void
+ecore_x_selection_primary_request(Ecore_X_Window w, const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_PRIMARY, target);
+}
+
+EAPI void
+ecore_x_selection_secondary_request(Ecore_X_Window w, const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_SECONDARY, target);
+}
+
+EAPI void
+ecore_x_selection_xdnd_request(Ecore_X_Window w, const char *target)
+{
+ Ecore_X_Atom atom;
+ Ecore_X_DND_Target *_target;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _target = _ecore_x_dnd_target_get();
+ atom = _ecore_x_selection_target_atom_get(target);
+ XConvertSelection(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, atom,
+ ECORE_X_ATOM_SELECTION_PROP_XDND, w,
+ _target->time);
+}
+
+EAPI void
+ecore_x_selection_clipboard_request(Ecore_X_Window w, const char *target)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_CLIPBOARD, target);
+}
+
+EAPI void
+ecore_x_selection_converter_atom_add(Ecore_X_Atom target,
+ int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret))
+{
+ Ecore_X_Selection_Converter *cnv;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ cnv = converters;
+ if (converters)
+ {
+ while (1)
+ {
+ if (cnv->target == target)
+ {
+ cnv->convert = func;
+ return;
+ }
+ if (cnv->next)
+ cnv = cnv->next;
+ else
+ break;
+ }
+
+ cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ cnv = cnv->next;
+ }
+ else
+ {
+ converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
+ cnv = converters;
+ }
+ cnv->target = target;
+ cnv->convert = func;
+}
+
+EAPI void
+ecore_x_selection_converter_add(char *target,
+ int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret))
+{
+ Ecore_X_Atom x_target;
+
+ if (!func || !target)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ x_target = _ecore_x_selection_target_atom_get(target);
+
+ ecore_x_selection_converter_atom_add(x_target, func);
+}
+
+EAPI void
+ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
+{
+ Ecore_X_Selection_Converter *cnv, *prev_cnv;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prev_cnv = NULL;
+ cnv = converters;
+
+ while (cnv)
+ {
+ if (cnv->target == target)
+ {
+ if (prev_cnv)
+ prev_cnv->next = cnv->next;
+ else
+ converters = cnv->next; /* This was the first converter */
+ free(cnv);
+
+ return;
+ }
+ prev_cnv = cnv;
+ cnv = cnv->next;
+ }
+}
+
+EAPI void
+ecore_x_selection_converter_del(char *target)
+{
+ Ecore_X_Atom x_target;
+
+ if (!target)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ x_target = _ecore_x_selection_target_atom_get(target);
+ ecore_x_selection_converter_atom_del(x_target);
+}
+
+EAPI int
+ecore_x_selection_notify_send(Ecore_X_Window requestor, Ecore_X_Atom selection, Ecore_X_Atom target, Ecore_X_Atom property, Ecore_X_Time time)
+{
+ XEvent xev;
+ XSelectionEvent xnotify;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xnotify.type = SelectionNotify;
+ xnotify.display = _ecore_x_disp;
+ xnotify.requestor = requestor;
+ xnotify.selection = selection;
+ xnotify.target = target;
+ xnotify.property = property;
+ xnotify.time = time;
+ xnotify.send_event = True;
+ xnotify.serial = 0;
+
+ xev.xselection = xnotify;
+ return ((XSendEvent(_ecore_x_disp, requestor, False, 0, &xev) > 0) ? 1 : 0);
+}
+
+/* Locate and run conversion callback for specified selection target */
+EAPI int
+ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret)
+{
+ Ecore_X_Selection_Intern *sel;
+ Ecore_X_Selection_Converter *cnv;
+ void *data;
+ int size;
+ char *tgt_str;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ sel = _ecore_x_selection_get(selection);
+ tgt_str = _ecore_x_selection_target_get(target);
+
+ for (cnv = converters; cnv; cnv = cnv->next)
+ {
+ if (cnv->target == target)
+ {
+ int r;
+ r = cnv->convert(tgt_str, sel->data, sel->length, &data, &size);
+ free(tgt_str);
+ if (r)
+ {
+ *data_ret = data;
+ return r;
+ }
+ else
+ return 0;
+ }
+ }
+
+ /* ICCCM says "If the selection cannot be converted into a form based on the target (and parameters, if any), the owner should refuse the SelectionRequest as previously described." */
+ return 0;
+
+ /* Default, just return the data
+ *data_ret = malloc(sel->length);
+ memcpy(*data_ret, sel->data, sel->length);
+ free(tgt_str);
+ return 1;
+ */
+}
+
+/* TODO: We need to work out a mechanism for automatic conversion to any requested
+ * locale using Ecore_Txt functions */
+/* Converter for standard non-utf8 text targets */
+static int
+_ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret)
+{
+ XTextProperty text_prop;
+ char *mystr;
+ XICCEncodingStyle style;
+
+ if (!data || !size)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
+ style = XTextStyle;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
+ style = XCompoundTextStyle;
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
+ style = XStringStyle;
+#ifdef X_HAVE_UTF8_STRING
+ else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
+ style = XUTF8StringStyle;
+#endif
+ else
+ return 0;
+
+ if (!(mystr = strdup(data)))
+ return 0;
+
+#ifdef X_HAVE_UTF8_STRING
+ if (Xutf8TextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success)
+ {
+ int bufsize = strlen((char *)text_prop.value) + 1;
+ *data_ret = malloc(bufsize);
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ free(mystr);
+ return 1;
+ }
+#else
+ if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success)
+ {
+ int bufsize = strlen(text_prop.value) + 1;
+ *data_ret = malloc(bufsize);
+ memcpy(*data_ret, text_prop.value, bufsize);
+ *size_ret = bufsize;
+ XFree(text_prop.value);
+ free(mystr);
+ return 1;
+ }
+#endif
+ else
+ {
+ free(mystr);
+ return 0;
+ }
+}
+
+EAPI void
+ecore_x_selection_parser_add(const char *target,
+ void *(*func)(const char *target, void *data, int size, int format))
+{
+ Ecore_X_Selection_Parser *prs;
+
+ if (!target)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prs = parsers;
+ if (parsers)
+ {
+ while (prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ prs->parse = func;
+ return;
+ }
+ prs = prs->next;
+ }
+
+ prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ prs = prs->next;
+ }
+ else
+ {
+ parsers = calloc(1, sizeof(Ecore_X_Selection_Parser));
+ prs = parsers;
+ }
+ prs->target = strdup(target);
+ prs->parse = func;
+}
+
+EAPI void
+ecore_x_selection_parser_del(const char *target)
+{
+ Ecore_X_Selection_Parser *prs, *prev_prs;
+
+ if (!target)
+ return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prev_prs = NULL;
+ prs = parsers;
+
+ while (prs)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ if (prev_prs)
+ prev_prs->next = prs->next;
+ else
+ parsers = prs->next; /* This was the first parser */
+ free(prs->target);
+ free(prs);
+
+ return;
+ }
+ prev_prs = prs;
+ prs = prs->next;
+ }
+}
+
+/* Locate and run conversion callback for specified selection target */
+void *
+_ecore_x_selection_parse(const char *target, void *data, int size, int format)
+{
+ Ecore_X_Selection_Parser *prs;
+ Ecore_X_Selection_Data *sel;
+
+ for (prs = parsers; prs; prs = prs->next)
+ {
+ if (!strcmp(prs->target, target))
+ {
+ sel = prs->parse(target, data, size, format);
+ return sel;
+ }
+ }
+
+ /* Default, just return the data */
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data));
+ sel->free = _ecore_x_selection_data_default_free;
+ sel->length = size;
+ sel->format = format;
+ sel->data = data;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_default_free(void *data)
+{
+ Ecore_X_Selection_Data *sel;
+
+ sel = data;
+ free(sel->data);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_files(const char *target, void *_data, int size, int format __UNUSED__)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ char *data = _data;
+ int i, is;
+ char *tmp;
+
+ if (strcmp(target, "text/uri-list") &&
+ strcmp(target, "_NETSCAPE_URL"))
+ return NULL;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files));
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free;
+
+ if (data[size - 1])
+ {
+ /* Isn't nul terminated */
+ size++;
+ data = realloc(data, size);
+ data[size - 1] = 0;
+ }
+
+ tmp = malloc(size);
+ i = 0;
+ is = 0;
+ while ((is < size) && (data[is]))
+ {
+ if ((i == 0) && (data[is] == '#'))
+ {
+ for (; ((data[is]) && (data[is] != '\n')); is++);
+ }
+ else
+ {
+ if ((data[is] != '\r') &&
+ (data[is] != '\n'))
+ {
+ tmp[i++] = data[is++];
+ }
+ else
+ {
+ while ((data[is] == '\r') || (data[is] == '\n')) is++;
+ tmp[i] = 0;
+ sel->num_files++;
+ sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ tmp[0] = 0;
+ i = 0;
+ }
+ }
+ }
+ if (i > 0)
+ {
+ tmp[i] = 0;
+ sel->num_files++;
+ sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
+ sel->files[sel->num_files - 1] = strdup(tmp);
+ }
+ free(tmp);
+ free(data);
+
+ ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES;
+ ECORE_X_SELECTION_DATA(sel)->length = sel->num_files;
+
+ return ECORE_X_SELECTION_DATA(sel);
+}
+
+static int
+_ecore_x_selection_data_files_free(void *data)
+{
+ Ecore_X_Selection_Data_Files *sel;
+ int i;
+
+ sel = data;
+ if (sel->files)
+ {
+ for (i = 0; i < sel->num_files; i++)
+ free(sel->files[i]);
+ free(sel->files);
+ }
+ free(sel);
+ return 0;
+}
+
+static void *
+_ecore_x_selection_parser_text(const char *target __UNUSED__, void *_data, int size, int format __UNUSED__)
+{
+ Ecore_X_Selection_Data_Text *sel;
+ char *data = _data;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
+
+ if (data[size - 1])
+ {
+ /* Isn't nul terminated */
+ size++;
+ data = realloc(data, size);
+ data[size - 1] = 0;
+ }
+
+ sel->text = (char *)data;
+ ECORE_X_SELECTION_DATA(sel)->length = size;
+ ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT;
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_text_free(void *data)
+{
+ Ecore_X_Selection_Data_Text *sel;
+
+ sel = data;
+ free(sel->text);
+ free(sel);
+ return 1;
+}
+
+static void *
+_ecore_x_selection_parser_targets(const char *target __UNUSED__, void *data, int size, int format __UNUSED__)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ unsigned long *targets;
+ int i;
+
+ sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets));
+ targets = (unsigned long *)data;
+
+ sel->num_targets = size - 2;
+ sel->targets = malloc((size - 2) * sizeof(char *));
+ for (i = 2; i < size; i++)
+ sel->targets[i - 2] = XGetAtomName(_ecore_x_disp, targets[i]);
+ free(data);
+
+ ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_targets_free;
+ ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS;
+ ECORE_X_SELECTION_DATA(sel)->length = size;
+ return sel;
+}
+
+static int
+_ecore_x_selection_data_targets_free(void *data)
+{
+ Ecore_X_Selection_Data_Targets *sel;
+ int i;
+
+ sel = data;
+
+ if (sel->targets)
+ {
+ for (i = 0; i < sel->num_targets; i++)
+ XFree(sel->targets[i]);
+ free(sel->targets);
+ }
+ free(sel);
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * XSync code
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+EAPI Ecore_X_Sync_Alarm
+ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter)
+{
+ Ecore_X_Sync_Alarm alarm;
+ XSyncAlarmAttributes values;
+ XSyncValue init;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&init, 0);
+ XSyncSetCounter(_ecore_x_disp, counter, init);
+
+ values.trigger.counter = counter;
+ values.trigger.value_type = XSyncAbsolute;
+ XSyncIntToValue(&values.trigger.wait_value, 1);
+ values.trigger.test_type = XSyncPositiveComparison;
+
+ XSyncIntToValue(&values.delta, 1);
+
+ values.events = True;
+
+ alarm = XSyncCreateAlarm(_ecore_x_disp,
+ XSyncCACounter |
+ XSyncCAValueType |
+ XSyncCAValue |
+ XSyncCATestType |
+ XSyncCADelta |
+ XSyncCAEvents,
+ &values);
+
+ ecore_x_sync();
+ return alarm;
+}
+
+EAPI int
+ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return XSyncDestroyAlarm(_ecore_x_disp, alarm);
+}
+
+EAPI int
+ecore_x_sync_counter_query(Ecore_X_Sync_Counter counter, unsigned int *val)
+{
+ XSyncValue value;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (XSyncQueryCounter(_ecore_x_disp, counter, &value))
+ {
+ *val = (unsigned int) XSyncValueLow32(value);
+ return 1;
+ }
+
+ return 0;
+}
+
+EAPI Ecore_X_Sync_Counter
+ecore_x_sync_counter_new(int val)
+{
+ XSyncCounter counter;
+ XSyncValue v;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&v, val);
+ counter = XSyncCreateCounter(_ecore_x_disp, v);
+ return counter;
+}
+
+EAPI void
+ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncDestroyCounter(_ecore_x_disp, counter);
+}
+
+EAPI void
+ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, int by)
+{
+ XSyncValue v;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncIntToValue(&v, by);
+ XSyncChangeCounter(_ecore_x_disp, counter, v);
+}
+
+EAPI void
+ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, int val)
+{
+ XSyncWaitCondition cond;
+ XSyncValue v, v2;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSyncQueryCounter(_ecore_x_disp, counter, &v);
+ XSyncIntToValue(&v, val);
+ XSyncIntToValue(&v2, val + 1);
+ cond.trigger.counter = counter;
+ cond.trigger.value_type = XSyncAbsolute;
+ cond.trigger.wait_value = v;
+ cond.trigger.test_type = XSyncPositiveComparison;
+ cond.event_threshold = v2;
+ XSyncAwait(_ecore_x_disp, &cond, 1);
+// XSync(_ecore_x_disp, False); // dont need this
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#ifdef ECORE_XTEST
+# include <X11/extensions/XTest.h>
+#endif
+
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include <string.h>
+
+
+EAPI int
+ecore_x_test_fake_key_down(const char *key)
+{
+#ifdef ECORE_XTEST
+ KeyCode keycode = 0;
+ KeySym keysym;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol) return 0;
+ keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
+ }
+ if (keycode == 0) return 0;
+ return XTestFakeKeyEvent(_ecore_x_disp, keycode, 1, 0);
+#else
+ return 0;
+#endif
+}
+
+EAPI int
+ecore_x_test_fake_key_up(const char *key)
+{
+#ifdef ECORE_XTEST
+ KeyCode keycode = 0;
+ KeySym keysym;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol) return 0;
+ keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
+ }
+ if (keycode == 0) return 0;
+ return XTestFakeKeyEvent(_ecore_x_disp, keycode, 0, 0);
+#else
+ return 0;
+#endif
+}
+
+EAPI int
+ecore_x_test_fake_key_press(const char *key)
+{
+#ifdef ECORE_XTEST
+ KeyCode keycode = 0;
+ KeySym keysym = 0;
+ int shift = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!strncmp(key, "Keycode-", 8))
+ keycode = atoi(key + 8);
+ else
+ {
+ keysym = XStringToKeysym(key);
+ if (keysym == NoSymbol) return 0;
+ keycode = XKeysymToKeycode(_ecore_x_disp, keysym);
+ if (XKeycodeToKeysym(_ecore_x_disp, keycode, 0) != keysym)
+ {
+ if (XKeycodeToKeysym(_ecore_x_disp, keycode, 1) == keysym)
+ shift = 1;
+ else
+ keycode = 0;
+ }
+ else
+ shift = 0;
+ }
+ if (keycode == 0)
+ {
+ static int mod = 0;
+ KeySym *keysyms;
+ int keycode_min, keycode_max, keycode_num;
+ int i;
+
+ XDisplayKeycodes(_ecore_x_disp, &keycode_min, &keycode_max);
+ keysyms = XGetKeyboardMapping(_ecore_x_disp, keycode_min,
+ keycode_max - keycode_min + 1,
+ &keycode_num);
+ mod = (mod + 1) & 0x7;
+ i = (keycode_max - keycode_min - mod - 1) * keycode_num;
+
+ keysyms[i] = keysym;
+ XChangeKeyboardMapping(_ecore_x_disp, keycode_min, keycode_num,
+ keysyms, (keycode_max - keycode_min));
+ XFree(keysyms);
+ XSync(_ecore_x_disp, False);
+ keycode = keycode_max - mod - 1;
+ }
+ if (shift)
+ XTestFakeKeyEvent(_ecore_x_disp,
+ XKeysymToKeycode(_ecore_x_disp, XK_Shift_L), 1, 0);
+ XTestFakeKeyEvent(_ecore_x_disp, keycode, 1, 0);
+ XTestFakeKeyEvent(_ecore_x_disp, keycode, 0, 0);
+ if (shift)
+ XTestFakeKeyEvent(_ecore_x_disp,
+ XKeysymToKeycode(_ecore_x_disp, XK_Shift_L), 0, 0);
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+EAPI const char *
+ecore_x_keysym_string_get(int keysym)
+{
+ return XKeysymToString(keysym);
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+static int ignore_num = 0;
+static Ecore_X_Window *ignore_list = NULL;
+
+/**
+ * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
+ *
+ * Functions that can be used to create an X window.
+ */
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp);
+ attr.backing_store = NotUseful;
+ attr.override_redirect = False;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ CopyFromParent, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ InputOutput,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWBackingStore |
+ CWOverrideRedirect |
+/* CWColormap | */
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask |
+ CWBitGravity |
+ CWWinGravity,
+ &attr);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp)) ecore_x_window_defaults_set(win);
+ return win;
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp);
+ attr.backing_store = NotUseful;
+ attr.override_redirect = True;
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.save_under = False;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ CopyFromParent, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ InputOutput,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWBackingStore |
+ CWOverrideRedirect |
+/* CWColormap | */
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask |
+ CWBitGravity |
+ CWWinGravity,
+ &attr);
+ return win;
+}
+
+/**
+ * Creates a new input window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+ Window win;
+ XSetWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp);
+ attr.override_redirect = True;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ CopyFromParent,
+ InputOnly,
+ CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
+ CWOverrideRedirect |
+ CWDontPropagate |
+ CWEventMask,
+ &attr);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp))
+ {
+ }
+ return win;
+}
+
+/**
+ * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
+ *
+ * Functions that set window properties.
+ */
+
+/**
+ * Sets the default properties for the given window.
+ *
+ * The default properties set for the window are @c WM_CLIENT_MACHINE and
+ * @c _NET_WM_PID.
+ *
+ * @param win The given window.
+ * @ingroup Ecore_X_Window_Properties_Groups
+ */
+EAPI void
+ecore_x_window_defaults_set(Ecore_X_Window win)
+{
+ long pid;
+ char buf[MAXHOSTNAMELEN];
+ char *hostname[1];
+ int argc;
+ char **argv;
+ XTextProperty xprop;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /*
+ * Set WM_CLIENT_MACHINE.
+ */
+ gethostname(buf, MAXHOSTNAMELEN);
+ buf[MAXHOSTNAMELEN - 1] = '\0';
+ hostname[0] = buf;
+ /* The ecore function uses UTF8 which Xlib may not like (especially
+ * with older clients) */
+ /* ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE,
+ (char *)buf); */
+ if (XStringListToTextProperty(hostname, 1, &xprop))
+ {
+ XSetWMClientMachine(_ecore_x_disp, win, &xprop);
+ XFree(xprop.value);
+ }
+
+ /*
+ * Set _NET_WM_PID
+ */
+ pid = getpid();
+ ecore_x_netwm_pid_set(win, pid);
+
+ ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL);
+
+ ecore_app_args_get(&argc, &argv);
+ ecore_x_icccm_command_set(win, argc, argv);
+}
+
+EAPI void
+ecore_x_window_configure(Ecore_X_Window win,
+ Ecore_X_Window_Configure_Mask mask,
+ int x, int y, int w, int h,
+ int border_width, Ecore_X_Window sibling,
+ int stack_mode)
+{
+ XWindowChanges xwc;
+
+ if (!win) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ xwc.x = x;
+ xwc.y = y;
+ xwc.width = w;
+ xwc.height = h;
+ xwc.border_width = border_width;
+ xwc.sibling = sibling;
+ xwc.stack_mode = stack_mode;
+
+ XConfigureWindow(_ecore_x_disp, win, mask, &xwc);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
+ *
+ * Functions to destroy X windows.
+ */
+
+/**
+ * Deletes the given window.
+ * @param win The given window.
+ * @ingroup Ecore_X_Window_Destroy_Group
+ */
+EAPI void
+ecore_x_window_free(Ecore_X_Window win)
+{
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win) XDestroyWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Set if a window should be ignored.
+ * @param win The given window.
+ * @param ignore if to ignore
+ */
+EAPI void
+ecore_x_window_ignore_set(Ecore_X_Window win, int ignore)
+{
+ int i, j;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (ignore)
+ {
+ if (ignore_list)
+ {
+ for (i = 0; i < ignore_num; i++)
+ {
+ if (win == ignore_list[i])
+ return;
+ }
+ ignore_list = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
+ if (!ignore_list) return;
+ ignore_list[ignore_num++] = win;
+ }
+ else
+ {
+ ignore_num = 0;
+ ignore_list = malloc(sizeof(Ecore_X_Window));
+ ignore_list[ignore_num++] = win;
+ }
+ }
+ else
+ {
+ if (!ignore_list) return;
+ for (i = 0, j = 0; i < ignore_num; i++)
+ {
+ if (win != ignore_list[i])
+ ignore_list[i] = ignore_list[j++];
+ else
+ ignore_num--;
+ }
+ ignore_list = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
+ }
+}
+
+/**
+ * Get the ignore list
+ * @param num number of windows in the list
+ * @return list of windows to ignore
+ */
+EAPI Ecore_X_Window *
+ecore_x_window_ignore_list(int *num)
+{
+ if (num) *num = ignore_num;
+ return ignore_list;
+}
+
+/**
+ * Sends a delete request to the given window.
+ * @param win The given window.
+ * @ingroup Ecore_X_Window_Destroy_Group
+ */
+EAPI void
+ecore_x_window_delete_request_send(Ecore_X_Window win)
+{
+ XEvent xev;
+
+ /* sorry sir, deleting the root window doesn't sound like
+ * a smart idea.
+ */
+ if (!win) return;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = _ecore_x_disp;
+ xev.xclient.window = win;
+ xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = ECORE_X_ATOM_WM_DELETE_WINDOW;
+ xev.xclient.data.l[1] = CurrentTime;
+
+ XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
+ *
+ * Functions to access and change the visibility of X windows.
+ */
+
+/**
+ * Shows a window.
+ *
+ * Synonymous to "mapping" a window in X Window System terminology.
+ *
+ * @param win The window to show.
+ * @ingroup Ecore_X_Window_Visibility
+ */
+EAPI void
+ecore_x_window_show(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XMapWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Hides a window.
+ *
+ * Synonymous to "unmapping" a window in X Window System terminology.
+ *
+ * @param win The window to hide.
+ * @ingroup Ecore_X_Window_Visibility
+ */
+EAPI void
+ecore_x_window_hide(Ecore_X_Window win)
+{
+ XEvent xev;
+ Window root;
+ int idum;
+ unsigned int uidum;
+
+ /* ICCCM: SEND unmap event... */
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ root = win;
+ if (ScreenCount(_ecore_x_disp) == 1)
+ root = DefaultRootWindow(_ecore_x_disp);
+ else
+ XGetGeometry(_ecore_x_disp, win, &root, &idum, &idum, &uidum, &uidum, &uidum, &uidum);
+ xev.xunmap.type = UnmapNotify;
+ xev.xunmap.serial = 0;
+ xev.xunmap.send_event = True;
+ xev.xunmap.display = _ecore_x_disp;
+ xev.xunmap.event = root;
+ xev.xunmap.window = win;
+ xev.xunmap.from_configure = False;
+ XSendEvent(_ecore_x_disp, xev.xunmap.event, False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ XUnmapWindow(_ecore_x_disp, win);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
+ *
+ * Functions that change or retrieve the geometry of X windows.
+ */
+
+/**
+ * Moves a window to the position @p x, @p y.
+ *
+ * The position is relative to the upper left hand corner of the
+ * parent window.
+ *
+ * @param win The window to move.
+ * @param x X position.
+ * @param y Y position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_move(Ecore_X_Window win, int x, int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XMoveWindow(_ecore_x_disp, win, x, y);
+}
+
+/**
+ * Resizes a window.
+ * @param win The window to resize.
+ * @param w New width of the window.
+ * @param h New height of the window.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_resize(Ecore_X_Window win, int w, int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ XResizeWindow(_ecore_x_disp, win, w, h);
+}
+
+/**
+ * Moves and resizes a window.
+ * @param win The window to move and resize.
+ * @param x New X position of the window.
+ * @param y New Y position of the window.
+ * @param w New width of the window.
+ * @param h New height of the window.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ XMoveResizeWindow(_ecore_x_disp, win, x, y, w, h);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
+ *
+ * Functions that give the focus to an X Window.
+ */
+
+/**
+ * Sets the focus to the window @p win.
+ * @param win The window to focus.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+EAPI void
+ecore_x_window_focus(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+// XSetInputFocus(_ecore_x_disp, win, RevertToNone, CurrentTime);
+// XSetInputFocus(_ecore_x_disp, win, RevertToPointerRoot, CurrentTime);
+ XSetInputFocus(_ecore_x_disp, win, RevertToParent, CurrentTime);
+}
+
+/**
+ * Sets the focus to the given window at a specific time.
+ * @param win The window to focus.
+ * @param t When to set the focus to the window.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+EAPI void
+ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time t)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+// XSetInputFocus(_ecore_x_disp, win, RevertToNone, t);
+// XSetInputFocus(_ecore_x_disp, win, PointerRoot, t);
+ XSetInputFocus(_ecore_x_disp, win, RevertToParent, t);
+}
+
+/**
+ * gets the focus to the window @p win.
+ * @return The window that has focus.
+ * @ingroup Ecore_X_Window_Focus_Functions
+ */
+EAPI Ecore_X_Window
+ecore_x_window_focus_get(void)
+{
+ Window win;
+ int revert_mode;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ win = 0;
+ XGetInputFocus(_ecore_x_disp, &win, &revert_mode);
+ return win;
+}
+
+/**
+ * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions
+ *
+ * Functions that change the Z order of X windows.
+ */
+
+/**
+ * Raises the given window.
+ * @param win The window to raise.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+EAPI void
+ecore_x_window_raise(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XRaiseWindow(_ecore_x_disp, win);
+}
+
+/**
+ * Lowers the given window.
+ * @param win The window to lower.
+ * @ingroup Ecore_X_Window_Z_Order_Group
+ */
+EAPI void
+ecore_x_window_lower(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XLowerWindow(_ecore_x_disp, win);
+}
+
+/**
+ * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions
+ *
+ * Functions that retrieve or changes the parent window of a window.
+ */
+
+/**
+ * Moves a window to within another window at a given position.
+ * @param win The window to reparent.
+ * @param new_parent The new parent window.
+ * @param x X position within new parent window.
+ * @param y Y position within new parent window.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI void
+ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (new_parent == 0) new_parent = DefaultRootWindow(_ecore_x_disp);
+ XReparentWindow(_ecore_x_disp, win, new_parent, x, y);
+}
+
+/**
+ * Retrieves the size of the given window.
+ * @param win The given window.
+ * @param w Pointer to an integer into which the width is to be stored.
+ * @param h Pointer to an integer into which the height is to be stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h)
+{
+ int dummy_x, dummy_y;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ ecore_x_drawable_geometry_get(win, &dummy_x, &dummy_y, w, h);
+}
+
+/**
+ * Retrieves the geometry of the given window.
+ * @param win The given window.
+ * @param x Pointer to an integer in which the X position is to be stored.
+ * @param y Pointer to an integer in which the Y position is to be stored.
+ * @param w Pointer to an integer in which the width is to be stored.
+ * @param h Pointer to an integer in which the height is to be stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!win) win = DefaultRootWindow(_ecore_x_disp);
+ ecore_x_drawable_geometry_get(win, x, y, w, h);
+}
+
+/**
+ * Retrieves the width of the border of the given window.
+ * @param win The given window.
+ * @return Width of the border of @p win.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI int
+ecore_x_window_border_width_get(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* doesn't make sense to call this on a root window */
+ if (!win) return 0;
+ return ecore_x_drawable_border_width_get(win);
+}
+
+/**
+ * Sets the width of the border of the given window.
+ * @param win The given window.
+ * @param width The new border width.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_border_width_set(Ecore_X_Window win, int width)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* doesn't make sense to call this on a root window */
+ if (!win) return;
+ XSetWindowBorderWidth (_ecore_x_disp, win, width);
+}
+
+/**
+ * Retrieves the depth of the given window.
+ * @param win The given window.
+ * @return Depth of the window.
+ */
+EAPI int
+ecore_x_window_depth_get(Ecore_X_Window win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_drawable_depth_get(win);
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI void
+ecore_x_window_cursor_show(Ecore_X_Window win, int show)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (!show)
+ {
+ Cursor c;
+ XColor cl;
+ Pixmap p, m;
+ GC gc;
+ XGCValues gcv;
+
+ p = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
+ m = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
+ gc = XCreateGC(_ecore_x_disp, m, 0, &gcv);
+ XSetForeground(_ecore_x_disp, gc, 0);
+ XDrawPoint(_ecore_x_disp, m, gc, 0, 0);
+ XFreeGC(_ecore_x_disp, gc);
+ c = XCreatePixmapCursor(_ecore_x_disp, p, m, &cl, &cl, 0, 0);
+ XDefineCursor(_ecore_x_disp, win, c);
+ XFreeCursor(_ecore_x_disp, c);
+ XFreePixmap(_ecore_x_disp, p);
+ XFreePixmap(_ecore_x_disp, m);
+ }
+ else
+ {
+ XDefineCursor(_ecore_x_disp, win, 0);
+ }
+}
+
+EAPI void
+ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor c)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (c == 0)
+ XUndefineCursor(_ecore_x_disp, win);
+ else
+ XDefineCursor(_ecore_x_disp, win, c);
+}
+
+/**
+ * Finds out whether the given window is currently visible.
+ * @param win The given window.
+ * @return 1 if the window is visible, otherwise 0.
+ * @ingroup Ecore_X_Window_Visibility_Group
+ */
+EAPI int
+ecore_x_window_visible_get(Ecore_X_Window win)
+{
+ XWindowAttributes attr;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return (XGetWindowAttributes(_ecore_x_disp, win, &attr) &&
+ (attr.map_state == IsViewable));
+}
+
+
+
+typedef struct _Shadow Shadow;
+struct _Shadow
+{
+ Shadow *parent;
+ Shadow **children;
+ Window win;
+ int children_num;
+ short x, y;
+ unsigned short w, h;
+};
+
+static Shadow **shadow_base = NULL;
+static int shadow_num = 0;
+
+static Shadow *
+_ecore_x_window_tree_walk(Window win)
+{
+ Window *list = NULL;
+ Window parent_win = 0, root_win = 0;
+ unsigned int num;
+ Shadow *s, **sl;
+ XWindowAttributes att;
+
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att)) return NULL;
+// if (att.class == InputOnly) return NULL;
+ if (att.map_state != IsViewable) return NULL;
+
+ s = calloc(1, sizeof(Shadow));
+ if (!s) return NULL;
+ s->win = win;
+ s->x = att.x;
+ s->y = att.y;
+ s->w = att.width;
+ s->h = att.height;
+ if (XQueryTree(_ecore_x_disp, s->win, &root_win, &parent_win,
+ &list, &num))
+ {
+ s->children = calloc(1, sizeof(Shadow *) * num);
+ if (s->children)
+ {
+ size_t i, j;
+ s->children_num = num;
+ for (i = 0; i < num; i++)
+ {
+ s->children[i] = _ecore_x_window_tree_walk(list[i]);
+ if (s->children[i]) s->children[i]->parent = s;
+ }
+ /* compress list down */
+ j = 0;
+ for (i = 0; i < num; i++)
+ {
+ if (s->children[i])
+ {
+ s->children[j] = s->children[i];
+ j++;
+ }
+ }
+ if (j == 0)
+ {
+ free(s->children);
+ s->children = NULL;
+ s->children_num = 0;
+ }
+ else
+ {
+ s->children_num = j;
+ sl = realloc(s->children, sizeof(Shadow *) * j);
+ if (sl) s->children = sl;
+ }
+ }
+ }
+ if (list) XFree(list);
+ return s;
+}
+
+static void
+_ecore_x_window_tree_shadow_free1(Shadow *s)
+{
+ int i;
+
+ if (!s) return;
+ if (s->children)
+ {
+ for (i = 0; i < s->children_num; i++)
+ {
+ if (s->children[i])
+ _ecore_x_window_tree_shadow_free1(s->children[i]);
+ }
+ free(s->children);
+ }
+ free(s);
+}
+
+static void
+_ecore_x_window_tree_shadow_free(void)
+{
+ int i;
+
+ if (!shadow_base) return;
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+ _ecore_x_window_tree_shadow_free1(shadow_base[i]);
+ }
+ free(shadow_base);
+ shadow_base = NULL;
+ shadow_num = 0;
+}
+
+static void
+_ecore_x_window_tree_shadow_populate(void)
+{
+ Ecore_X_Window *roots;
+ int i, num;
+
+ roots = ecore_x_window_root_list(&num);
+ if (roots)
+ {
+ shadow_base = calloc(1, sizeof(Shadow *) * num);
+ if (shadow_base)
+ {
+ shadow_num = num;
+ for (i = 0; i < num; i++)
+ shadow_base[i] = _ecore_x_window_tree_walk(roots[i]);
+ }
+ free(roots);
+ }
+}
+
+/*
+static int shadow_count = 0;
+
+static void
+_ecore_x_window_tree_shadow_start(void)
+{
+ shadow_count++;
+ if (shadow_count > 1) return;
+ _ecore_x_window_tree_shadow_populate();
+}
+
+static void
+_ecore_x_window_tree_shadow_stop(void)
+{
+ shadow_count--;
+ if (shadow_count != 0) return;
+ _ecore_x_window_tree_shadow_free();
+}
+*/
+
+static Shadow *
+_ecore_x_window_shadow_tree_find_shadow(Shadow *s, Window win)
+{
+ Shadow *ss;
+ int i;
+
+ if (s->win == win) return s;
+ if (s->children)
+ {
+ for (i = 0; i < s->children_num; i++)
+ {
+ if (!s->children[i]) continue;
+ if ((ss = _ecore_x_window_shadow_tree_find_shadow(s->children[i], win)))
+ return ss;
+ }
+ }
+ return NULL;
+}
+
+static Shadow *
+_ecore_x_window_shadow_tree_find(Window base)
+{
+ Shadow *s;
+ int i;
+
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+ if ((s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], base)))
+ return s;
+ }
+ return NULL;
+}
+
+static Window
+_ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow *s, int bx, int by, int x, int y,
+ Ecore_X_Window *skip, int skip_num)
+{
+ Window child;
+ int i, j;
+ int wx, wy;
+
+ wx = s->x + bx;
+ wy = s->y + by;
+ if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h))))
+ return 0;
+ if (s->children)
+ {
+ int skipit = 0;
+
+ for (i = s->children_num - 1; i >= 0; --i)
+ {
+ if (!s->children[i]) continue;
+ skipit = 0;
+ if (skip)
+ {
+ for (j = 0; j < skip_num; j++)
+ {
+ if (s->children[i]->win == skip[j])
+ {
+ skipit = 1;
+ goto onward;
+ }
+ }
+ }
+ onward:
+ if (!skipit)
+ {
+ if ((child = _ecore_x_window_shadow_tree_at_xy_get_shadow(s->children[i], wx, wy, x, y, skip, skip_num)))
+ {
+ return child;
+ }
+ }
+ }
+ }
+ return s->win;
+}
+
+static Window
+_ecore_x_window_shadow_tree_at_xy_get(Window base, int bx, int by, int x, int y,
+ Ecore_X_Window *skip, int skip_num)
+{
+ Shadow *s;
+
+ if (!shadow_base)
+ {
+ _ecore_x_window_tree_shadow_populate();
+ if (!shadow_base) return 0;
+ }
+ s = _ecore_x_window_shadow_tree_find(base);
+ if (!s) return 0;
+ return _ecore_x_window_shadow_tree_at_xy_get_shadow(s, bx, by, x, y, skip, skip_num);
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but skips the windows in the list. This uses a shadow tree built from the
+ * window tree that is only updated the first time
+ * ecore_x_window_shadow_tree_at_xy_with_skip_get() is called, or the next time
+ * it is called after a ecore_x_window_shadow_tree_flush()
+ * @param base The base window to start searching from (normally root).
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base, int x, int y, Ecore_X_Window *skip, int skip_num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_shadow_tree_at_xy_get(base, 0, 0, x, y, skip, skip_num);
+}
+
+/**
+ * Retrieves the parent window a given window has. This uses the shadow window
+ * tree.
+ * @param root The root window of @p win - if 0, this will be automatically determined with extra processing overhead
+ * @param win The window to get the parent window of
+ * @return The parent window of @p win
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_shadow_parent_get(Ecore_X_Window root __UNUSED__, Ecore_X_Window win)
+{
+ Shadow *s;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!shadow_base)
+ {
+ _ecore_x_window_tree_shadow_populate();
+ if (!shadow_base) return 0;
+ }
+ for (i = 0; i < shadow_num; i++)
+ {
+ if (!shadow_base[i]) continue;
+ s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], win);
+ if (s)
+ {
+ if (!s->parent) return 0;
+ return s->parent->win;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Flushes the window shadow tree so nothing is stored.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI void
+ecore_x_window_shadow_tree_flush(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ _ecore_x_window_tree_shadow_free();
+}
+
+/**
+ * Retrieves the root window a given window is on.
+ * @param win The window to get the root window of
+ * @return The root window of @p win
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_root_get(Ecore_X_Window win)
+{
+ XWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att)) return 0;
+ return att.root;
+}
+
+static Window
+_ecore_x_window_at_xy_get(Window base, int bx, int by, int x, int y,
+ Ecore_X_Window *skip, int skip_num)
+{
+ Window *list = NULL;
+ Window parent_win = 0, child = 0, root_win = 0;
+ int i, j, wx, wy, ww, wh;
+ unsigned int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!ecore_x_window_visible_get(base))
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
+ wx += bx;
+ wy += by;
+
+ if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XQueryTree(_ecore_x_disp, base, &root_win, &parent_win, &list, &num))
+ return base;
+
+ if (list)
+ {
+ int skipit = 0;
+
+ for (i = num - 1; i >= 0; --i)
+ {
+ skipit = 0;
+
+ if (skip)
+ {
+ for (j = 0; j < skip_num; j++)
+ {
+ if (list[i] == skip[j])
+ {
+ skipit = 1;
+ goto onward;
+ }
+ }
+ }
+ onward:
+ if (!skipit)
+ {
+ if ((child = _ecore_x_window_at_xy_get(list[i], wx, wy, x, y, skip, skip_num)))
+ {
+ XFree(list);
+ return child;
+ }
+ }
+ }
+ XFree(list);
+ }
+ return base;
+}
+
+/**
+ * Retrieves the top, visible window at the given location.
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_get(int x, int y)
+{
+ Ecore_X_Window win, root;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* FIXME: Proper function to determine current root/virtual root
+ * window missing here */
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_grab();
+ win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ return win ? win : root;
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but skips the windows in the list.
+ * @param x The given X position.
+ * @param y The given Y position.
+ * @return The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_with_skip_get(int x, int y, Ecore_X_Window *skip, int skip_num)
+{
+ Ecore_X_Window win, root;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* FIXME: Proper function to determine current root/virtual root
+ * window missing here */
+ root = DefaultRootWindow(_ecore_x_disp);
+
+ ecore_x_grab();
+ win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
+ ecore_x_ungrab();
+
+ return win ? win : root;
+}
+
+EAPI Ecore_X_Window
+ecore_x_window_at_xy_begin_get(Ecore_X_Window begin, int x, int y)
+{
+ Ecore_X_Window win;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_grab();
+ win = _ecore_x_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
+ ecore_x_ungrab();
+
+ return win ? win : begin;
+}
+
+/**
+ * Retrieves the parent window of the given window.
+ * @param win The given window.
+ * @return The parent window of @p win.
+ * @ingroup Ecore_X_Window_Parent_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_parent_get(Ecore_X_Window win)
+{
+ Window root, parent, *children = NULL;
+ unsigned int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XQueryTree(_ecore_x_disp, win, &root, &parent, &children, &num))
+ return 0;
+ if (children)
+ XFree(children);
+
+ return parent;
+}
+
+/**
+ * Sets the background color of the given window.
+ * @param win The given window
+ * @param r red value (0...65536, 16 bits)
+ * @param g green value (0...65536, 16 bits)
+ * @param b blue value (0...65536, 16 bits)
+ */
+EAPI void
+ecore_x_window_background_color_set(Ecore_X_Window win, unsigned short r,
+ unsigned short g, unsigned short b)
+{
+ XSetWindowAttributes attr;
+ Colormap map;
+ XColor col;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ col.red = r;
+ col.green = g;
+ col.blue = b;
+
+ map = DefaultColormap(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
+ XAllocColor(_ecore_x_disp, map, &col);
+
+ attr.background_pixel = col.pixel;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWBackPixel, &attr);
+}
+
+EAPI void
+ecore_x_window_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav)
+{
+ XSetWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ att.win_gravity = grav;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWWinGravity, &att);
+}
+
+EAPI void
+ecore_x_window_pixel_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav)
+{
+ XSetWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ att.bit_gravity = grav;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWBitGravity, &att);
+}
+
+EAPI void
+ecore_x_window_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pmap)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XSetWindowBackgroundPixmap(_ecore_x_disp, win, pmap);
+}
+
+EAPI void
+ecore_x_window_area_clear(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XClearArea(_ecore_x_disp, win, x, y, w, h, False);
+}
+
+EAPI void
+ecore_x_window_area_expose(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XClearArea(_ecore_x_disp, win, x, y, w, h, True);
+}
+
+EAPI void
+ecore_x_window_override_set(Ecore_X_Window win, int override)
+{
+ XSetWindowAttributes att;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ att.override_redirect = override;
+ XChangeWindowAttributes(_ecore_x_disp, win, CWOverrideRedirect, &att);
+}
+
+#ifdef ECORE_XRENDER
+static Ecore_X_Window
+_ecore_x_window_argb_internal_new(Ecore_X_Window parent, int x, int y, int w, int h, int override, int saveunder)
+{
+ Window win;
+ XSetWindowAttributes attr;
+ XWindowAttributes att;
+ XVisualInfo *xvi;
+ XVisualInfo vi_in;
+ int nvi, i, scr = 0;
+ XRenderPictFormat *fmt;
+ Visual *vis;
+
+ if (parent == 0)
+ {
+ parent = DefaultRootWindow(_ecore_x_disp);
+ scr = DefaultScreen(_ecore_x_disp);
+ }
+ else
+ {
+ /* ewww - round trip */
+ XGetWindowAttributes(_ecore_x_disp, parent, &att);
+ for (i = 0; i < ScreenCount(_ecore_x_disp); i++)
+ {
+ if (att.screen == ScreenOfDisplay(_ecore_x_disp, i))
+ {
+ scr = i;
+ break;
+ }
+ }
+ }
+ vi_in.screen = scr;
+ vi_in.depth = 32;
+ vi_in.class = TrueColor;
+ xvi = XGetVisualInfo(_ecore_x_disp,
+ VisualScreenMask |
+ VisualDepthMask |
+ VisualClassMask,
+ &vi_in,
+ &nvi);
+ if (xvi == NULL) return 0;
+ vis = NULL;
+ for (i = 0; i < nvi; i++)
+ {
+ fmt = XRenderFindVisualFormat(_ecore_x_disp, xvi[i].visual);
+ if ((fmt->type == PictTypeDirect) && (fmt->direct.alphaMask))
+ {
+ vis = xvi[i].visual;
+ break;
+ }
+ }
+ XFree (xvi);
+
+ attr.backing_store = NotUseful;
+ attr.override_redirect = override;
+ attr.colormap = XCreateColormap(_ecore_x_disp, parent,
+ vis, AllocNone);
+ attr.border_pixel = 0;
+ attr.background_pixmap = None;
+ attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.save_under = saveunder;
+ attr.do_not_propagate_mask = NoEventMask;
+ attr.event_mask = KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ EnterWindowMask |
+ LeaveWindowMask |
+ PointerMotionMask |
+ ExposureMask |
+ VisibilityChangeMask |
+ StructureNotifyMask |
+ FocusChangeMask |
+ PropertyChangeMask |
+ ColormapChangeMask;
+ win = XCreateWindow(_ecore_x_disp, parent,
+ x, y, w, h, 0,
+ 32,
+ InputOutput,
+ vis,
+ CWBackingStore |
+ CWOverrideRedirect |
+ CWColormap |
+ CWBorderPixel |
+ CWBackPixmap |
+ CWSaveUnder |
+ CWDontPropagate |
+ CWEventMask |
+ CWBitGravity |
+ CWWinGravity,
+ &attr);
+ XFreeColormap(_ecore_x_disp, attr.colormap);
+
+ if (parent == DefaultRootWindow(_ecore_x_disp)) ecore_x_window_defaults_set(win);
+ return win;
+}
+#endif
+
+EAPI int
+ecore_x_window_argb_get(Ecore_X_Window win)
+{
+#ifdef ECORE_XRENDER
+ XWindowAttributes att;
+ XRenderPictFormat *fmt;
+
+ att.visual = 0;
+ if (!XGetWindowAttributes(_ecore_x_disp, win, &att)) return 0;
+ fmt = XRenderFindVisualFormat(_ecore_x_disp, att.visual);
+ if (!fmt) return 0;
+ if ((fmt->type == PictTypeDirect) && (fmt->direct.alphaMask)) return 1;
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_manager_argb_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+#ifdef ECORE_XRENDER
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 1, 0);
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Creates a new window.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_argb_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+#ifdef ECORE_XRENDER
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 0, 0);
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Creates a window with the override redirect attribute set to @c True.
+ * @param parent The parent window to use. If @p parent is @c 0, the root
+ * window of the default display is used.
+ * @param x X position.
+ * @param y Y position.
+ * @param w Width.
+ * @param h Height.
+ * @return The new window handle.
+ * @ingroup Ecore_X_Window_Create_Group
+ */
+EAPI Ecore_X_Window
+ecore_x_window_override_argb_new(Ecore_X_Window parent, int x, int y, int w, int h)
+{
+#ifdef ECORE_XRENDER
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 1, 0);
+#else
+ return 0;
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+#include <inttypes.h>
+#include <limits.h>
+
+#define _ATOM_SET_CARD32(win, atom, p_val, cnt) \
+ XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \
+ (unsigned char *)p_val, cnt)
+
+/*
+ * Set CARD32 (array) property
+ */
+EAPI void
+ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int num)
+{
+#if SIZEOF_INT == SIZEOF_LONG
+ _ATOM_SET_CARD32(win, atom, val, num);
+#else
+ long *v2;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ v2 = malloc(num * sizeof(long));
+ if (!v2)
+ return;
+ for (i = 0; i < num; i++)
+ v2[i] = val[i];
+ _ATOM_SET_CARD32(win, atom, v2, num);
+ free(v2);
+#endif
+}
+
+/*
+ * Get CARD32 (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int *val, unsigned int len)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ unsigned int i;
+ int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ XA_CARDINAL, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if (type_ret != XA_CARDINAL || format_ret != 32)
+ {
+ num = -1;
+ }
+ else if (num_ret == 0 || !prop_ret)
+ {
+ num = 0;
+ }
+ else
+ {
+ if (num_ret < len)
+ len = num_ret;
+ for (i = 0; i < len; i++)
+ val[i] = ((unsigned long *)prop_ret)[i];
+ num = len;
+ }
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * Get CARD32 (array) property of any length
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_card32_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ unsigned int **plst)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ unsigned int i, *val;
+ int num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ *plst = NULL;
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ XA_CARDINAL, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if (type_ret != XA_CARDINAL || format_ret != 32)
+ {
+ num = -1;
+ }
+ else if (num_ret == 0 || !prop_ret)
+ {
+ num = 0;
+ }
+ else
+ {
+ val = malloc(num_ret * sizeof(unsigned int));
+ for (i = 0; i < num_ret; i++)
+ val[i] = ((unsigned long *)prop_ret)[i];
+ num = num_ret;
+ *plst = val;
+ }
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * Set X ID (array) property
+ */
+EAPI void
+ecore_x_window_prop_xid_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom type, Ecore_X_ID * lst,
+ unsigned int num)
+{
+#if SIZEOF_INT == SIZEOF_LONG
+ XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
+ (unsigned char *)lst, num);
+#else
+ unsigned long *pl;
+ unsigned int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ pl = malloc(num * sizeof(long));
+ if (!pl)
+ return;
+ for (i = 0; i < num; i++)
+ pl[i] = lst[i];
+ XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
+ (unsigned char *)pl, num);
+ free(pl);
+#endif
+}
+
+/*
+ * Get X ID (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_xid_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom type, Ecore_X_ID * lst,
+ unsigned int len)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ int num;
+ unsigned i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ type, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if (type_ret != type || format_ret != 32)
+ {
+ num = -1;
+ }
+ else if (num_ret == 0 || !prop_ret)
+ {
+ num = 0;
+ }
+ else
+ {
+ if (num_ret < len)
+ len = num_ret;
+ for (i = 0; i < len; i++)
+ lst[i] = ((unsigned long *)prop_ret)[i];
+ num = len;
+ }
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * Get X ID (array) property
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * The returned array must be freed with free().
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_xid_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom type, Ecore_X_ID ** val)
+{
+ unsigned char *prop_ret;
+ Atom type_ret;
+ unsigned long bytes_after, num_ret;
+ int format_ret;
+ Ecore_X_Atom *alst;
+ int num;
+ unsigned i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ *val = NULL;
+ prop_ret = NULL;
+ if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
+ type, &type_ret, &format_ret, &num_ret,
+ &bytes_after, &prop_ret) != Success)
+ return -1;
+
+ if (type_ret != type || format_ret != 32)
+ {
+ num = -1;
+ }
+ else if (num_ret == 0 || !prop_ret)
+ {
+ num = 0;
+ }
+ else
+ {
+ alst = malloc(num_ret * sizeof(Ecore_X_ID));
+ for (i = 0; i < num_ret; i++)
+ alst[i] = ((unsigned long *)prop_ret)[i];
+ num = num_ret;
+ *val = alst;
+ }
+ if (prop_ret)
+ XFree(prop_ret);
+
+ return num;
+}
+
+/*
+ * Remove/add/toggle X ID list item.
+ */
+EAPI void
+ecore_x_window_prop_xid_list_change(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom type, Ecore_X_ID item, int op)
+{
+ Ecore_X_ID *lst;
+ int i, num;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
+ if (num < 0)
+ return; /* Error - assuming invalid window */
+
+ /* Is it there? */
+ for (i = 0; i < num; i++)
+ {
+ if (lst[i] == item)
+ break;
+ }
+
+ if (i < num)
+ {
+ /* Was in list */
+ if (op == ECORE_X_PROP_LIST_ADD)
+ goto done;
+ /* Remove it */
+ num--;
+ for (; i < num; i++)
+ lst[i] = lst[i + 1];
+ }
+ else
+ {
+ /* Was not in list */
+ if (op == ECORE_X_PROP_LIST_REMOVE)
+ goto done;
+ /* Add it */
+ num++;
+ lst = realloc(lst, num * sizeof(Ecore_X_ID));
+ lst[i] = item;
+ }
+
+ ecore_x_window_prop_xid_set(win, atom, type, lst, num);
+
+ done:
+ if (lst)
+ free(lst);
+}
+
+/*
+ * Set Atom (array) property
+ */
+EAPI void
+ecore_x_window_prop_atom_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom * lst, unsigned int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_xid_set(win, atom, XA_ATOM, lst, num);
+}
+
+/*
+ * Get Atom (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_atom_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom * lst, unsigned int len)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_get(win, atom, XA_ATOM, lst, len);
+}
+
+/*
+ * Get Atom (array) property
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * The returned array must be freed with free().
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_atom_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom ** plst)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_list_get(win, atom, XA_ATOM, plst);
+}
+
+/*
+ * Remove/add/toggle atom list item.
+ */
+EAPI void
+ecore_x_window_prop_atom_list_change(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Atom item, int op)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_xid_list_change(win, atom, XA_ATOM, item, op);
+}
+
+/*
+ * Set Window (array) property
+ */
+EAPI void
+ecore_x_window_prop_window_set(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Window * lst, unsigned int num)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ecore_x_window_prop_xid_set(win, atom, XA_WINDOW, lst, num);
+}
+
+/*
+ * Get Window (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_window_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Window * lst, unsigned int len)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_get(win, atom, XA_WINDOW, lst, len);
+}
+
+/*
+ * Get Window (array) property
+ *
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * The returned array must be freed with free().
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+EAPI int
+ecore_x_window_prop_window_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
+ Ecore_X_Window ** plst)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ return ecore_x_window_prop_xid_list_get(win, atom, XA_WINDOW, plst);
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI Ecore_X_Atom
+ecore_x_window_prop_any_type(void)
+{
+ return AnyPropertyType;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI void
+ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, void *data, int number)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (size != 32)
+ XChangeProperty(_ecore_x_disp, win, property, type, size, PropModeReplace,
+ (unsigned char *)data, number);
+ else
+ {
+ unsigned long *dat;
+ int i, *ptr;
+
+ dat = malloc(sizeof(unsigned long) * number);
+ if (dat)
+ {
+ for (ptr = (int *)data, i = 0; i < number; i++) dat[i] = ptr[i];
+ XChangeProperty(_ecore_x_disp, win, property, type, size,
+ PropModeReplace, (unsigned char *)dat, number);
+ free(dat);
+ }
+ }
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI int
+ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size __UNUSED__, unsigned char **data, int *num)
+{
+ Atom type_ret = 0;
+ int ret, size_ret = 0;
+ unsigned long num_ret = 0, bytes = 0, i;
+ unsigned char *prop_ret = NULL;
+
+ /* make sure these are initialized */
+ if (num) *num = 0;
+
+ if (data)
+ *data = NULL;
+ else /* we can't store the retrieved data, so just return */
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!win) win = DefaultRootWindow(_ecore_x_disp);
+
+ ret = XGetWindowProperty(_ecore_x_disp, win, property, 0, LONG_MAX,
+ False, type, &type_ret, &size_ret,
+ &num_ret, &bytes, &prop_ret);
+
+ if (ret != Success)
+ return 0;
+
+ if (!num_ret) {
+ XFree(prop_ret);
+ return 0;
+ }
+
+ if (!(*data = malloc(num_ret * size_ret / 8))) {
+ XFree(prop_ret);
+ return 0;
+ }
+
+ switch (size_ret) {
+ case 8:
+ for (i = 0; i < num_ret; i++)
+ (*data)[i] = prop_ret[i];
+ break;
+ case 16:
+ for (i = 0; i < num_ret; i++)
+ ((unsigned short *) *data)[i] = ((unsigned short *) prop_ret)[i];
+ break;
+ case 32:
+ for (i = 0; i < num_ret; i++)
+ ((unsigned int *) *data)[i] = ((unsigned long *) prop_ret)[i];
+ break;
+ }
+
+ XFree(prop_ret);
+
+ if (num) *num = num_ret;
+ return size_ret;
+}
+
+EAPI void
+ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XDeleteProperty(_ecore_x_disp, win, property);
+}
+
+EAPI Ecore_X_Atom *
+ecore_x_window_prop_list(Ecore_X_Window win, int *num_ret)
+{
+ Ecore_X_Atom *atoms;
+ Atom *atom_ret;
+ int num = 0, i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num_ret) *num_ret = 0;
+
+ atom_ret = XListProperties(_ecore_x_disp, win, &num);
+ if (!atom_ret) return NULL;
+
+ atoms = malloc(num * sizeof(Ecore_X_Atom));
+ if (atoms)
+ {
+ for (i = 0; i < num; i++) atoms[i] = atom_ret[i];
+ if (num_ret) *num_ret = num;
+ }
+ XFree(atom_ret);
+ return atoms;
+}
+
+/**
+ * Set a window string property.
+ * @param win The window
+ * @param type The property
+ * @param str The string
+ *
+ * Set a window string property
+ */
+EAPI void
+ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str)
+{
+ XTextProperty xtp;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ xtp.value = (unsigned char *)str;
+ xtp.format = 8;
+ xtp.encoding = ECORE_X_ATOM_UTF8_STRING;
+ xtp.nitems = strlen(str);
+ XSetTextProperty(_ecore_x_disp, win, &xtp, type);
+}
+
+/**
+ * Get a window string property.
+ * @param win The window
+ * @param type The property
+ *
+ * Return window string property of a window. String must be free'd when done.
+ */
+EAPI char *
+ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type)
+{
+ XTextProperty xtp;
+ char *str = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (win == 0) win = DefaultRootWindow(_ecore_x_disp);
+ if (XGetTextProperty(_ecore_x_disp, win, &xtp, type))
+ {
+ int items;
+ char **list = NULL;
+ Status s;
+
+ if (xtp.encoding == ECORE_X_ATOM_UTF8_STRING)
+ {
+ str = strdup((char *)xtp.value);
+ }
+ else
+ {
+#ifdef X_HAVE_UTF8_STRING
+ s = Xutf8TextPropertyToTextList(_ecore_x_disp, &xtp,
+ &list, &items);
+#else
+ s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp,
+ &list, &items);
+#endif
+ if ((s == XLocaleNotSupported) ||
+ (s == XNoMemory) || (s == XConverterNotFound))
+ {
+ str = strdup((char *)xtp.value);
+ }
+ else if ((s >= Success) && (items > 0))
+ {
+ str = strdup(list[0]);
+ }
+ if (list)
+ XFreeStringList(list);
+ }
+ XFree(xtp.value);
+ }
+ return str;
+}
+
+EAPI int
+ecore_x_window_prop_protocol_isset(Ecore_X_Window win,
+ Ecore_X_WM_Protocol protocol)
+{
+ Atom proto, *protos = NULL;
+ int i, ret = 0, protos_count = 0;
+
+ /* check for invalid values */
+ if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
+ return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ proto = _ecore_x_atoms_wm_protocols[protocol];
+
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return ret;
+
+ for (i = 0; i < protos_count; i++)
+ if (protos[i] == proto)
+ {
+ ret = 1;
+ break;
+ }
+
+ XFree(protos);
+
+ return ret;
+}
+
+/**
+ * To be documented.
+ *
+ * FIXME: To be fixed.
+ */
+EAPI Ecore_X_WM_Protocol *
+ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret)
+{
+ Atom *protos = NULL;
+ int i, protos_count = 0;
+ Ecore_X_WM_Protocol *prot_ret = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
+ return NULL;
+
+ if ((!protos) || (protos_count <= 0)) return NULL;
+ prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol));
+ if (!prot_ret)
+ {
+ XFree(protos);
+ return NULL;
+ }
+ for (i = 0; i < protos_count; i++)
+ {
+ Ecore_X_WM_Protocol j;
+
+ prot_ret[i] = -1;
+ for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
+ {
+ if (_ecore_x_atoms_wm_protocols[j] == protos[i])
+ prot_ret[i] = j;
+ }
+ }
+ XFree(protos);
+ *num_ret = protos_count;
+ return prot_ret;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+/**
+ * @defgroup Ecore_X_Window_Shape X Window Shape Functions
+ *
+ * These functions use the shape extension of the X server to change
+ * shape of given windows.
+ */
+
+/**
+ * Sets the shape of the given window to that given by the pixmap @p mask.
+ * @param win The given window.
+ * @param mask A 2-bit depth pixmap that provides the new shape of the
+ * window.
+ * @ingroup Ecore_X_Window_Shape
+ */
+EAPI void
+ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineMask(_ecore_x_disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
+}
+
+EAPI void
+ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, 0, 0, shape_win, ShapeBounding, ShapeSet);
+}
+
+EAPI void
+ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, x, y, shape_win, ShapeBounding, ShapeSet);
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeSet, Unsorted);
+}
+
+EAPI void
+ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num)
+{
+ XRectangle *rect = NULL;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num > 0)
+ {
+ rect = malloc(sizeof(XRectangle) * num);
+ if (rect)
+ {
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ else
+ num = 0;
+ }
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, rect, num, ShapeSet, Unsorted);
+ if (rect) free(rect);
+}
+
+EAPI void
+ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, 0, 0, shape_win, ShapeBounding, ShapeUnion);
+}
+
+EAPI void
+ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, x, y, shape_win, ShapeBounding, ShapeUnion);
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, Unsorted);
+}
+
+EAPI void
+ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h)
+{
+ XRectangle rect;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeIntersect, Unsorted);
+}
+
+EAPI void
+ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num)
+{
+ XRectangle *rect = NULL;
+ int i;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (num > 0)
+ {
+ rect = malloc(sizeof(XRectangle) * num);
+ if (rect)
+ {
+ for (i = 0; i < num; i++)
+ {
+ rect[i].x = rects[i].x;
+ rect[i].y = rects[i].y;
+ rect[i].width = rects[i].width;
+ rect[i].height = rects[i].height;
+ }
+ }
+ else
+ num = 0;
+ }
+ XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, rect, num, ShapeUnion, Unsorted);
+ if (rect) free(rect);
+}
+
+EAPI Ecore_X_Rectangle *
+ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret)
+{
+ XRectangle *rect;
+ Ecore_X_Rectangle *rects = NULL;
+ int i, num = 0, ord;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeBounding, &num, &ord);
+ if (rect)
+ {
+ rects = malloc(sizeof(Ecore_X_Rectangle) * num);
+ if (rects)
+ {
+ for (i = 0; i < num; i++)
+ {
+ rects[i].x = rect[i].x;
+ rects[i].y = rect[i].y;
+ rects[i].width = rect[i].width;
+ rects[i].height = rect[i].height;
+ }
+ }
+ XFree(rect);
+ }
+ if (num_ret) *num_ret = num;
+ return rects;
+}
+
+EAPI void
+ecore_x_window_shape_events_select(Ecore_X_Window win, int on)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (on)
+ XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask);
+ else
+ XShapeSelectInput(_ecore_x_disp, win, 0);
+}
+
+/**
+ * Sets the input shape of the given window to that given by the pixmap @p mask.
+ * @param win The given window.
+ * @param mask A 2-bit depth pixmap that provides the new input shape of the
+ * window.
+ * @ingroup Ecore_X_Window_Shape
+ */
+EAPI void
+ecore_x_window_shape_input_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef ShapeInput
+ XShapeCombineMask(_ecore_x_disp, win, ShapeInput, 0, 0, mask, ShapeSet);
+#else
+ XShapeCombineMask(_ecore_x_disp, win, ShapeBounding, 0, 0, mask, ShapeSet);
+#endif
+}
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+
+#ifdef ECORE_XI2
+#include "Ecore_Input.h"
+#endif
+
+int _ecore_x_xi2_opcode = -1;
+
+#ifdef ECORE_XI2
+static XIDeviceInfo *_ecore_x_xi2_devs = NULL;
+static int _ecore_x_xi2_num = 0;
+#endif
+
+void
+_ecore_x_input_init(void)
+{
+#ifdef ECORE_XI2
+ int event, error;
+ int major = 2, minor = 0;
+
+ if (!XQueryExtension(_ecore_x_disp, "XInputExtension",
+ &_ecore_x_xi2_opcode, &event, &error))
+ {
+ _ecore_x_xi2_opcode = -1;
+ return;
+ }
+
+ if (XIQueryVersion(_ecore_x_disp, &major, &minor) == BadRequest)
+ {
+ _ecore_x_xi2_opcode = -1;
+ return;
+ }
+ _ecore_x_xi2_devs = XIQueryDevice(_ecore_x_disp, XIAllDevices,
+ &_ecore_x_xi2_num);
+#endif
+}
+
+void
+_ecore_x_input_shutdown(void)
+{
+#ifdef ECORE_XI2
+ if (_ecore_x_xi2_devs)
+ {
+ XIFreeDeviceInfo(_ecore_x_xi2_devs);
+ _ecore_x_xi2_devs = NULL;
+ }
+ _ecore_x_xi2_num = 0;
+ _ecore_x_xi2_opcode = -1;
+#endif
+}
+
+void
+_ecore_x_input_handler(XEvent* xevent)
+{
+#ifdef ECORE_XI2
+ XIDeviceEvent *evd = (XIDeviceEvent *)(xevent->xcookie.data);
+ int devid = evd->deviceid;
+
+ //printf("deviceID = %d\n", devid);
+ switch (xevent->xcookie.evtype)
+ {
+ case XI_Motion:
+ _ecore_mouse_move
+ (evd->time,
+ 0, // state
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+ case XI_ButtonPress:
+ _ecore_mouse_button
+ (ECORE_EVENT_MOUSE_BUTTON_DOWN,
+ evd->time,
+ 0, // state
+ 0, // button
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+ case XI_ButtonRelease:
+ _ecore_mouse_button
+ (ECORE_EVENT_MOUSE_BUTTON_UP,
+ evd->time,
+ 0, // state
+ 0, // button
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y,
+ evd->event,
+ (evd->child ? evd->child : evd->event),
+ evd->root,
+ 1, // same_screen
+ devid, 1, 1,
+ 1.0, // pressure
+ 0.0, // angle
+ evd->event_x, evd->event_y,
+ evd->root_x, evd->root_y);
+ break;
+ }
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_input_multi_select(Ecore_X_Window win)
+{
+#ifdef ECORE_XI2
+ int i, find = 0;
+
+ if (!_ecore_x_xi2_devs) return 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ for (i = 0; i < _ecore_x_xi2_num; i++)
+ {
+ XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]);
+
+ if (dev->use == XIFloatingSlave)
+ {
+ XIEventMask eventmask;
+ unsigned char mask[1] = { 0 };
+
+ eventmask.deviceid = dev->deviceid;
+ eventmask.mask_len = sizeof(mask);
+ eventmask.mask = mask;
+ XISetMask(mask, XI_ButtonPress);
+ XISetMask(mask, XI_ButtonRelease);
+ XISetMask(mask, XI_Motion);
+ XISelectEvents(_ecore_x_disp, win, &eventmask, 1);
+ find = 1;
+ }
+ }
+
+ return find;
+#else
+ return 0;
+#endif
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+/*
+ * Xinerama code
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_x_private.h"
+#include "Ecore_X.h"
+#include "Ecore_X_Atoms.h"
+
+#ifdef ECORE_XINERAMA
+static XineramaScreenInfo *_xin_info = NULL;
+static int _xin_scr_num = 0;
+#endif
+
+EAPI int
+ecore_x_xinerama_screen_count_get(void)
+{
+#ifdef ECORE_XINERAMA
+ int event_base, error_base;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (_xin_info) XFree(_xin_info);
+ _xin_info = NULL;
+ if (XineramaQueryExtension(_ecore_x_disp, &event_base, &error_base))
+ {
+ _xin_info = XineramaQueryScreens(_ecore_x_disp, &_xin_scr_num);
+ if (_xin_info) return _xin_scr_num;
+ }
+#endif
+ return 0;
+}
+
+EAPI int
+ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef ECORE_XINERAMA
+ if (_xin_info)
+ {
+ int i;
+
+ for (i = 0; i < _xin_scr_num; i++)
+ {
+ if (_xin_info[i].screen_number == screen)
+ {
+ if (x) *x = _xin_info[i].x_org;
+ if (y) *y = _xin_info[i].y_org;
+ if (w) *w = _xin_info[i].width;
+ if (h) *h = _xin_info[i].height;
+ return 1;
+ }
+ }
+ }
+#endif
+ if (x) *x = 0;
+ if (y) *y = 0;
+ if (w) *w = DisplayWidth(_ecore_x_disp, 0);
+ if (h) *h = DisplayHeight(_ecore_x_disp, 0);
+ return 0;
+}
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
+@EINA_CFLAGS@ \
+@CHECK_CFLAGS@
+
+if EFL_ENABLE_TESTS
+
+check_PROGRAMS = ecore_suite
+
+ecore_suite_SOURCES = \
+ecore_suite.c \
+ecore_test_ecore.c \
+ecore_test_ecore_con.c
+
+ecore_suite_LDADD = \
+@CHECK_LIBS@ \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_con/libecore_con.la
+
+endif
+
+EXTRA_DIST = ecore_suite.h
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Ecore.h>
+
+#include "ecore_suite.h"
+
+typedef struct _Ecore_Test_Case Ecore_Test_Case;
+
+struct _Ecore_Test_Case
+{
+ const char *test_case;
+ void (*build)(TCase *tc);
+};
+
+static const Ecore_Test_Case etc[] = {
+ { "Ecore", ecore_test_ecore },
+ { "Ecore_Con", ecore_test_ecore_con },
+ { NULL, NULL }
+};
+
+static void
+_list_tests(void)
+{
+ const Ecore_Test_Case *itr;
+
+ itr = etc;
+ fputs("Available Test Cases:\n", stderr);
+ for (; itr->test_case != NULL; itr++)
+ fprintf(stderr, "\t%s\n", itr->test_case);
+}
+static Eina_Bool
+_use_test(int argc, const char **argv, const char *test_case)
+{
+ if (argc < 1)
+ return 1;
+
+ for (; argc > 0; argc--, argv++)
+ if (strcmp(test_case, *argv) == 0)
+ return 1;
+ return 0;
+}
+
+static Suite *
+ecore_suite_build(int argc, const char **argv)
+{
+ TCase *tc;
+ Suite *s;
+ int i;
+
+ s = suite_create("Ecore");
+
+ for (i = 0; etc[i].test_case != NULL; ++i)
+ {
+ if (!_use_test(argc, argv, etc[i].test_case)) continue;
+ tc = tcase_create(etc[i].test_case);
+
+ etc[i].build(tc);
+
+ suite_add_tcase(s, tc);
+ tcase_set_timeout(tc, 0);
+ }
+
+ return s;
+}
+
+int
+main(int argc, char **argv)
+{
+ Suite *s;
+ SRunner *sr;
+ int i, failed_count;
+
+ for (i = 1; i < argc; i++)
+ if ((strcmp(argv[i], "-h") == 0) ||
+ (strcmp(argv[i], "--help") == 0))
+ {
+ fprintf(stderr, "Usage:\n\t%s [test_case1 .. [test_caseN]]\n",
+ argv[0]);
+ _list_tests();
+ return 0;
+ }
+ else if ((strcmp(argv[i], "-l") == 0) ||
+ (strcmp(argv[i], "--list") == 0))
+ {
+ _list_tests();
+ return 0;
+ }
+
+ s = ecore_suite_build(argc - 1, (const char **)argv + 1);
+ sr = srunner_create(s);
+
+ srunner_run_all(sr, CK_NORMAL);
+ failed_count = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (failed_count == 0) ? 0 : 255;
+}
--- /dev/null
+#ifndef _ECORE_SUITE_H
+#define _ECORE_SUITE_H
+
+#include <check.h>
+
+void ecore_test_ecore(TCase *tc);
+void ecore_test_ecore_con(TCase *tc);
+
+
+#endif /* _ECORE_SUITE_H */
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include <unistd.h>
+
+#include "ecore_suite.h"
+
+static int
+_quit_cb(void *data)
+{
+ Eina_Bool *val = data;
+ *val = EINA_TRUE;
+ ecore_main_loop_quit();
+ return 0;
+}
+
+static int
+_dummy_cb(void *data)
+{
+ return (int)(long)data;
+}
+
+START_TEST(ecore_test_ecore_init)
+{
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+START_TEST(ecore_test_ecore_main_loop)
+{
+ Eina_Bool did = EINA_FALSE;
+ Ecore_Timer *timer;
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ timer = ecore_timer_add(0.0, _quit_cb, &did);
+ fail_if(timer == NULL);
+
+ ecore_main_loop_begin();
+
+ fail_if(did == EINA_FALSE);
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+START_TEST(ecore_test_ecore_main_loop_idler)
+{
+ Eina_Bool did = EINA_FALSE;
+ Ecore_Idler *idler;
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ idler = ecore_idler_add(_quit_cb, &did);
+ fail_if(idler == NULL);
+
+ ecore_main_loop_begin();
+
+ fail_if(did == EINA_FALSE);
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+START_TEST(ecore_test_ecore_main_loop_idle_enterer)
+{
+ Eina_Bool did = EINA_FALSE;
+ Ecore_Idle_Enterer *idle_enterer;
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ idle_enterer = ecore_idle_enterer_add(_quit_cb, &did);
+ fail_if(idle_enterer == NULL);
+
+ ecore_main_loop_begin();
+
+ fail_if(did == EINA_FALSE);
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+START_TEST(ecore_test_ecore_main_loop_idle_exiter)
+{
+ Eina_Bool did = EINA_FALSE;
+ Ecore_Timer *timer;
+ Ecore_Idle_Exiter *idle_exiter;
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ /* make system exit idle */
+ timer = ecore_timer_add(0.0, _dummy_cb, (void *)(long)0);
+ fail_if(timer == NULL);
+
+ idle_exiter = ecore_idle_exiter_add(_quit_cb, &did);
+ fail_if(idle_exiter == NULL);
+
+ ecore_main_loop_begin();
+
+ fail_if(did == EINA_FALSE);
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+START_TEST(ecore_test_ecore_main_loop_timer)
+{
+ Eina_Bool did = EINA_FALSE;
+ Ecore_Timer *timer;
+ double start, end, elapsed;
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ timer = ecore_timer_add(2.0, _quit_cb, &did);
+ fail_if(timer == NULL);
+
+ start = ecore_time_get();
+ ecore_main_loop_begin();
+ end = ecore_time_get();
+ elapsed = end - start;
+
+ fail_if(did == EINA_FALSE);
+ fail_if(elapsed < 2.0);
+ fail_if(elapsed > 3.0); /* 1 second "error margin" */
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+static int
+_fd_handler_cb(void *data, Ecore_Fd_Handler *handler __UNUSED__)
+{
+ Eina_Bool *val = data;
+ *val = EINA_TRUE;
+ ecore_main_loop_quit();
+ return 0;
+}
+
+START_TEST(ecore_test_ecore_main_loop_fd_handler)
+{
+ Eina_Bool did = EINA_FALSE;
+ Ecore_Fd_Handler *fd_handler;
+ int comm[2];
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ ret = pipe(comm);
+ fail_if(ret != 0);
+
+ fd_handler = ecore_main_fd_handler_add
+ (comm[0], ECORE_FD_READ, _fd_handler_cb, &did, NULL, NULL);
+ fail_if(fd_handler == NULL);
+
+ ret = write(comm[1], &did, 1);
+ fail_if(ret != 1);
+
+ ecore_main_loop_begin();
+
+ close(comm[0]);
+ close(comm[1]);
+
+ fail_if(did == EINA_FALSE);
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+static int
+_event_handler_cb(void *data, int type __UNUSED__, void *event __UNUSED__)
+{
+ Eina_Bool *val = data;
+ *val = EINA_TRUE;
+ ecore_main_loop_quit();
+ return 0;
+}
+
+START_TEST(ecore_test_ecore_main_loop_event)
+{
+ Eina_Bool did = EINA_FALSE;
+ Ecore_Event_Handler *handler;
+ Ecore_Event *event;
+ int ret, type;
+
+ ret = ecore_init();
+ fail_if(ret != 1);
+
+ type = ecore_event_type_new();
+ fail_if(type < 1);
+
+ handler = ecore_event_handler_add(type, _event_handler_cb, &did);
+ fail_if(handler == NULL);
+
+ event = ecore_event_add(type, NULL, NULL, NULL);
+ fail_if(event == NULL);
+
+ ecore_main_loop_begin();
+
+ fail_if(did == EINA_FALSE);
+
+ ret = ecore_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+void ecore_test_ecore(TCase *tc)
+{
+ tcase_add_test(tc, ecore_test_ecore_init);
+ tcase_add_test(tc, ecore_test_ecore_main_loop);
+ tcase_add_test(tc, ecore_test_ecore_main_loop_idler);
+ tcase_add_test(tc, ecore_test_ecore_main_loop_idle_enterer);
+ tcase_add_test(tc, ecore_test_ecore_main_loop_idle_exiter);
+ tcase_add_test(tc, ecore_test_ecore_main_loop_timer);
+ tcase_add_test(tc, ecore_test_ecore_main_loop_fd_handler);
+ tcase_add_test(tc, ecore_test_ecore_main_loop_event);
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore_Con.h>
+
+#include "ecore_suite.h"
+
+
+START_TEST(ecore_test_ecore_con_init)
+{
+ int ret;
+
+ ret = ecore_con_init();
+ fail_if(ret != 1);
+
+ ret = ecore_con_shutdown();
+ fail_if(ret != 0);
+}
+END_TEST
+
+void ecore_test_ecore_con(TCase *tc)
+{
+ tcase_add_test(tc, ecore_test_ecore_con_init);
+}